Search code examples
c#.neterror-handlingasp.net-apicontroller

Custom Exception handling across multiple API Controllers in different Apps (.Net)


I have a central application that speaks to multiple other applications via a controller. Let's say that controller A (source) reaches out to Controller B for some data. At present, we return the data, and only the data (no timestamps, no user details, etc)

App 1: Controller A

public async Task<ActionResult<ExpectedType>> GetData(ModelType model)
{
    try
    {
        var response = await _dataFetchingBizLayer.GetThatDataFromApp2(model);
        return response;
    }
    catch (Exception ex)
    {
        _logger.Log(ex);
        return StatusCode(500, ex.Message); // "There was an issue."
    }
}

App 1: The _dataFetchingBizLayer (business logic layer)

 public async Task<ExpectedType> GetThatDataFromApp2(ModelType model)
 {
     var response = await _secondaryAppWrapper.GetThatData(
         new QueryModelType
         {
            //... shape the query data object
         });

     return response;
 }

App 2: Controller B

public ActionResult<ExpectedType> GetThatData(QueryModelType model)
{
    try
    {
        var response = _dataFetchingDAO.GetDataFromDB(model);
        return response;
    }
    catch (CustomException customEx)
    {
        _logger.Log(customEx);
        return StatusCode(500, customEx.Message); // "The error occurred at station B."
    }
}

With that said, Controller B has been written to include some custom exceptions that are thrown throughout various parts of the system where applicable. Unfortunately, when the Custom Exception is thrown in Controller B and returned, the exception seen in Controller A does not contain that custom message. Rather it outputs its own message as seen above.

I was able to find a workaround for this by using APIException in Controller A to catch the exceptions thrown by Controller B. I also have to update the return value for Controller B to return ex.Response and not ex.Message.

In Controller A:

catch (APIException apiEx)
{
    _logger.Log(apiEx);
    return StatusCode(500, apiEx.Response);
}

I'd like to know if there is a way for to transmit the custom message and status codes, along with catching the other exception types sent from Controller B into Controller A.

I am unsure if this is a viable solution long-term and I'm currently toying with the idea of creating custom response classes as a better solution.

Please let me know if there is any additional information needed.


Solution

  • I was able to find a solution for this by catching APIException in Controller A to catch the exceptions thrown by Controller B.

    Message Sent from Controller B:

    catch (CustomExceptionType customEx)
        {
            _logger.Log(customEx);
            return StatusCode(400, customEx.Message); // 'Bad data found here'
        }
    

    Exception caught in Controller A:

    catch (APIException apiEx)
    {
        _logger.Log(apiEx);
        return StatusCode(apiEx, apiEx.Response); // apiEx.Response = 'Bad data found here'
    }
    catch (Exception ex)
    {
        _logger.Log(ex);
        return StatusCode(500, ex.Message) // ex.Message = stringified custom exception
    }
    

    In the above code, the ex.Message was found to contain a stringified object containing 'StatusCode: 400 and Response: Bad data found here'

    Hope this helps someone :)