{"record":{"id":"8ce6267b4ba7a24a","repo":"MassTransit/MassTransit","slug":"disposeasync","errorCode":null,"errorMessage":"DisposeAsync","messagePattern":"DisposeAsync","errorType":"exception","errorClass":"MassTransitException","httpStatus":null,"severity":"error","filePath":"src/MassTransit/Util/DisposeAsyncExtensions.cs","lineNumber":28,"sourceCode":"        /// <summary>\n        /// Invoke the dispose callback, and then rethrow the exception\n        /// </summary>\n        /// <param name=\"exception\"></param>\n        /// <param name=\"disposeCallback\"></param>\n        /// <typeparam name=\"T\"></typeparam>\n        /// <returns></returns>\n        /// <exception cref=\"MassTransitException\"></exception>\n        public static ValueTask<T> DisposeAsync<T>(this Exception exception, Func<Task> disposeCallback)\n        {\n            var dispatchInfo = ExceptionDispatchInfo.Capture(exception.GetBaseException());\n\n            async ValueTask<T> Faulted()\n            {\n                await disposeCallback().ConfigureAwait(false);\n\n                dispatchInfo.Throw();\n\n                throw new MassTransitException(\"DisposeAsync\", exception);\n            }\n\n            return Faulted();\n        }\n\n        /// <summary>\n        /// Invoke the dispose callback, and then rethrow the exception\n        /// </summary>\n        /// <param name=\"exception\"></param>\n        /// <param name=\"disposeCallback\"></param>\n        /// <typeparam name=\"T\"></typeparam>\n        /// <returns></returns>\n        /// <exception cref=\"MassTransitException\"></exception>\n        public static ValueTask<T> DisposeAsync<T>(this Exception exception, Func<ValueTask> disposeCallback)\n        {\n            var dispatchInfo = ExceptionDispatchInfo.Capture(exception.GetBaseException());\n\n            async ValueTask<T> Faulted()","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/MassTransit/MassTransit/blob/62ab339afa3bac2e9b3fe1769d0d35d7e44778e9/src/MassTransit/Util/DisposeAsyncExtensions.cs#L10-L46","documentation":"This DisposeAsync extension guarantees the original exception is not lost: if the async-dispose callback itself faults, it runs the dispose callback, rethrows the captured dispatch exception via dispatchInfo.Throw(), and otherwise throws MassTransitException('DisposeAsync', exception) to wrap the failure. Seeing this means an exception occurred during an async disposable's DisposeAsync while a primary exception was already in flight.","triggerScenarios":"Calling DisposeAsync() on an async-disposable (e.g. a bus, client, or receive endpoint handle) when the underlying operation already faulted and the dispose callback also threw, or the captured exception could not be rethrown.","commonSituations":"Bus shutdown while a send/fault was pending; 'using await' scopes whose body threw and whose disposal also failed; cancellation during dispose; clients disposed in finally blocks after failures.","solutions":["Inspect the inner 'exception' property for the root cause — this wrapper masks a primary fault","Log both the disposal failure and the wrapped original exception","Fix the underlying operation failure that put the disposable into a faulted state","Ensure DisposeAsync is awaited and resources are not double-disposed"],"exampleFix":"// before\nawait client.DisposeAsync(); // hides wrapped fault\n// after\ntry { await client.DisposeAsync(); }\ncatch (MassTransitException ex) when (ex.Message == \"DisposeAsync\")\n{\n    _logger.LogError(ex.InnerException, \"Faulted during dispose\");\n    throw ex.InnerException ?? ex;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await x.DisposeAsync(); } catch (MassTransitException ex) { log(ex.InnerException ?? ex); }","preventionTips":["Await disposal; fix root faults"],"tags":["async-dispose","exception-wrapping","resource-cleanup"],"backgroundTag":"invalid-state-transition","analyzedSha":"62ab339afa3bac2e9b3fe1769d0d35d7e44778e9","analyzedAt":"2026-09-13T22:47:47.593Z","contentChangedAt":"2026-09-13T22:47:47.593Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}