internal async Task ProcessRequestAsync(HttpContextBase context)
        {
            Exception exception = _exceptionInfo.SourceException;

            Contract.Assert(exception != null);

            CancellationToken cancellationToken = CancellationToken.None;

            HttpResponseException responseException = exception as HttpResponseException;

            if (responseException != null)
            {
                // This method call is hardend and designed not to throw exceptions (since they won't be caught and
                // handled further by its callers).
                await HttpControllerHandler.CopyResponseAsync(context, context.GetOrCreateHttpRequestMessage(),
                                                              responseException.Response, cancellationToken);
            }
            else
            {
                // This method call is hardend and designed not to throw exceptions (since they won't be caught and
                // handled further by its callers).
                bool handled = await HttpControllerHandler.CopyErrorResponseAsync(
                    WebHostExceptionCatchBlocks.HttpWebRoute, context, context.GetOrCreateHttpRequestMessage(),
                    null, _exceptionInfo.SourceException, cancellationToken, _exceptionLogger, _exceptionHandler);

                if (!handled)
                {
                    _exceptionInfo.Throw();
                }
            }
        }
        internal async Task ProcessRequestAsync(HttpContextBase context)
        {
            Exception exception = _exceptionInfo.SourceException;

            Contract.Assert(exception != null);

            HttpRequestMessage  request           = context.GetOrCreateHttpRequestMessage();
            HttpResponseMessage response          = null;
            CancellationToken   cancellationToken = context.Response.GetClientDisconnectedTokenWhenFixed();

            HttpResponseException responseException = exception as HttpResponseException;

            try
            {
                if (responseException != null)
                {
                    response = responseException.Response;
                    Contract.Assert(response != null);

                    // This method call is hardened and designed not to throw exceptions (since they won't be caught
                    // and handled further by its callers).
                    await HttpControllerHandler.CopyResponseAsync(context, request, response, _exceptionLogger,
                                                                  _exceptionHandler, cancellationToken);
                }
                else
                {
                    // This method call is hardened and designed not to throw exceptions (since they won't be caught and
                    // handled further by its callers).
                    bool handled = await HttpControllerHandler.CopyErrorResponseAsync(
                        WebHostExceptionCatchBlocks.HttpWebRoute, context, request, null,
                        _exceptionInfo.SourceException, _exceptionLogger, _exceptionHandler, cancellationToken);

                    if (!handled)
                    {
                        _exceptionInfo.Throw();
                    }
                }
            }
            finally
            {
                // The other HttpTaskAsyncHandler is HttpControllerHandler; it has similar cleanup logic.
                request.DisposeRequestResources();
                request.Dispose();

                if (response != null)
                {
                    response.Dispose();
                }
            }
        }
        internal async Task ProcessRequestAsync(HttpContextBase context)
        {
            Exception exception = _exceptionInfo.SourceException;

            Contract.Assert(exception != null);

            OperationCanceledException canceledException = exception as OperationCanceledException;

            if (canceledException != null)
            {
                // If the route throws a cancelation exception, then we'll abort the request instead of
                // reporting an 'error'. We don't expect this to happen, but aborting the request is
                // consistent with our behavior in other hosts.
                context.Request.Abort();
                return;
            }

            HttpRequestMessage  request           = context.GetOrCreateHttpRequestMessage();
            HttpResponseMessage response          = null;
            CancellationToken   cancellationToken =
                context.Response.GetClientDisconnectedTokenWhenFixed();

            HttpResponseException responseException = exception as HttpResponseException;

            try
            {
                if (responseException != null)
                {
                    response = responseException.Response;
                    Contract.Assert(response != null);

                    // This method call is hardened and designed not to throw exceptions (since they won't be caught
                    // and handled further by its callers).
                    await HttpControllerHandler.CopyResponseAsync(
                        context,
                        request,
                        response,
                        _exceptionLogger,
                        _exceptionHandler,
                        cancellationToken
                        );
                }
                else
                {
                    // This method call is hardened and designed not to throw exceptions (since they won't be caught and
                    // handled further by its callers).
                    bool handled = await HttpControllerHandler.CopyErrorResponseAsync(
                        WebHostExceptionCatchBlocks.HttpWebRoute,
                        context,
                        request,
                        null,
                        _exceptionInfo.SourceException,
                        _exceptionLogger,
                        _exceptionHandler,
                        cancellationToken
                        );

                    if (!handled)
                    {
                        _exceptionInfo.Throw();
                    }
                }
            }
            catch (OperationCanceledException)
            {
                // This block handles cancellations that might occur while we're writing an 'error' response.
                //
                // HttpTaskAsyncHandler treats a canceled task as an unhandled exception (logged to Application event
                // log). Instead of returning a canceled task, abort the request and return a completed task.
                context.Request.Abort();
            }
            finally
            {
                // The other HttpTaskAsyncHandler is HttpControllerHandler; it has similar cleanup logic.
                request.DisposeRequestResources();
                request.Dispose();

                if (response != null)
                {
                    response.Dispose();
                }
            }
        }