Skip to content

Commit

Permalink
Handle Task Canceled exception and output 400 instead of 503 (#3081)
Browse files Browse the repository at this point in the history
* Handle TaskCanceled exception and output 400 instead of 503

* Simplify code
  • Loading branch information
bcarthic authored Oct 3, 2023
1 parent 04de4ff commit c585d32
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,30 @@ public async Task WhenExecutingExceptionMiddleware_GivenAnHttpContextWithNoExcep
Assert.Equal(0, _context.Response.Body.Length);
}

[Fact]
public async Task GivenAnAggregateExceptionHasTaskCanceled_WhenMiddlewareIsExecuted_ThenMessageShouldBeOverwritten()
{
var innerExceptions = new List<Exception>
{
new TaskCanceledException("Operation canceled"),
new ServiceUnavailableException()
};

var aggException = new AggregateException(innerExceptions);

ExceptionHandlingMiddleware baseExceptionMiddleware = CreateExceptionHandlingMiddleware(innerHttpContext => throw new DataStoreException(aggException));

baseExceptionMiddleware.ExecuteResultAsync(Arg.Any<HttpContext>(), Arg.Any<IActionResult>()).Returns(Task.CompletedTask);

await baseExceptionMiddleware.Invoke(_context);

await baseExceptionMiddleware
.Received()
.ExecuteResultAsync(
Arg.Any<HttpContext>(),
Arg.Is<ContentResult>(x => x.StatusCode.Value == (int)HttpStatusCode.BadRequest));
}

private static ExceptionHandlingMiddleware CreateExceptionHandlingMiddleware(RequestDelegate nextDelegate)
{
return Substitute.ForPartsOf<ExceptionHandlingMiddleware>(nextDelegate, NullLogger<ExceptionHandlingMiddleware>.Instance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using Microsoft.Health.Dicom.Core.Exceptions;
using NotSupportedException = Microsoft.Health.Dicom.Core.Exceptions.NotSupportedException;
using ComponentModelValidationException = System.ComponentModel.DataAnnotations.ValidationException;
using System.Linq;

namespace Microsoft.Health.Dicom.Api.Features.Exceptions;

Expand Down Expand Up @@ -85,7 +86,7 @@ private IActionResult MapExceptionToResult(Exception exception)
case AuditHeaderTooLargeException:
case ConnectionResetException:
case OperationCanceledException:
case DataStoreException e when e.InnerException is TaskCanceledException:
case DataStoreException e when IsTaskCanceledException(e.InnerException):
case BadHttpRequestException:
case IOException io when io.Message.Equals("The request stream was aborted.", StringComparison.OrdinalIgnoreCase):
statusCode = HttpStatusCode.BadRequest;
Expand Down Expand Up @@ -154,6 +155,11 @@ private IActionResult MapExceptionToResult(Exception exception)
return GetContentResult(statusCode, message);
}

private static bool IsTaskCanceledException(Exception ex)
{
return ex is TaskCanceledException || (ex is AggregateException aggEx && aggEx.InnerExceptions.Any(x => x is TaskCanceledException));
}

private static IActionResult GetContentResult(HttpStatusCode statusCode, string message)
{
return new ContentResult
Expand Down

0 comments on commit c585d32

Please sign in to comment.