SimpleIdServer icon indicating copy to clipboard operation
SimpleIdServer copied to clipboard

Can't handle SCIM Internal Server Errors

Open LazaroOnline opened this issue 2 years ago • 2 comments

We need a way to handle Internal server errors (500) generated in SCIM APIs that allows to handle the request in a different way and possibly return different responses other than 500 in the case of a known issue that should not be 500 but for example 400 instead.

The problem is those controllers are wrapped inside a try {... } catch (Exception ex) {} that catches all exceptions of all types in the BulkController.cs and the BaseApiController.cs. While I could write a middleware that checks if the response status code was 500, it is too late and the response was already sent to the client.

Possible solutions would be:

  • Re-throw the exception so it can be handled by the host application or some middleware.

  • Add a configuration event that is called when there is an internal server error, that receives the exception and the context with the request/response information, and returns whether the error was handled or not. So in the Startup service configuration a new option would be:

 services.AddSIDScim(options =>
{
    ....
    options.OnInternalServerError = MyOnInternalServerErrorHandler
});

function bool MyOnInternalServerErrorHandler(HttpContext context, Exception exception) {
  bool isHandled = false;
  if (IsKnownIssue(exception)) {
    context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
    context.Response.ContentType = MediaTypeNames.Application.Json;
    isHandled = true;
  }
  return isHandled ;
}

Then in SCIM BaseApiController.cs:

....
catch(Exception ex)
{
    var isHandledError = _options.OnInternalServerError?.Invoke(HttpContext, ex) ?? false;
    if (!isHandledError ) {
        _logger.LogError(ex, ex.Message);
        return this.BuildError(HttpStatusCode.InternalServerError, ex.Message, SCIMConstants.ErrorSCIMTypes.InternalServerError);
    }
}

LazaroOnline avatar Sep 04 '23 04:09 LazaroOnline

Hello,

First thank you for your proposal :) We have made some changes in the release\4.0.4 branch to support your requirement. You can easily subscribe to internal server errors like this and return a custom error message. If NULL is returned, then the default result will be returned. The function takes the following parameters on entry:

  • HttpContext
  • Exception
  • CancellationToken
services.AddSIDScim(_ =>
{
    _.IgnoreUnsupportedCanonicalValues = false;
    _.IsNoContentReturned = false;
    _.SCIMEvents = new SCIMHostEvents
    {
        OnInternalServerError = async (ctx, e, c) =>
        {
            var contentResult = new ContentResult();
            contentResult.StatusCode = 400;
            contentResult.Content = JsonSerializer.Serialize(new
            {
                message = "hello"
            });
            contentResult.ContentType = "application/json";
            return contentResult;
        }
    };
});

KR,

SID

simpleidserver avatar Sep 05 '23 21:09 simpleidserver

Thanks a lot! that's exactly what we needed in our project. I could not test it though because we need to migrate first to the latest version, but once we do we will use this!

LazaroOnline avatar Sep 07 '23 12:09 LazaroOnline