Error reporting in Azure Functions vs App Insights

Aron Kovacs 36 Reputation points
2021-10-11T15:10:14.7+00:00

We call REST based APIs hosted by Azure Functions and fail to implement a consistent error handling supporting App Insights and wonder what can be done about it: - If we don't handle exceptions of the function, then App Insights reports a 'failure', but the service returns only the the error code to the caller, but no error content: Hence, the client receives a 500 and thats it. - - If we handle the exception and log it (to AppInsights) then App Insights stops reporting a 'failure' hence monitoring on function level is broken. We can query for the exception, but they are out-of-context (i.e. we can see the exception by a custom query only) and we don't know which function is impacted actually. How to marry up the two needs: 1. Let the function fail so that AppInsights reports the failure (and monitor can alert) 2. Return a bit more meaningful error message to the caller than 500. Example on how it looks currently in AppInsights: ![139349-2021-10-11-13-07-40-presentation1-powerpoint.png][1] The failures are unhandled exceptions (but the client receives purely 500) The exceptions are handled exceptions logged with ILogger.LogError(ex, ex.Message...) (but App Insights doesn't see it as failure) [1]: /api/attachments/139349-2021-10-11-13-07-40-presentation1-powerpoint.png?platform=QnA

Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
4,248 questions
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Samara Soucy 76 Reputation points
    2021-10-12T00:09:50.463+00:00

    Unfortunately "success" in Functions is whether or not is successfully pushed something to the output binding for any type of output- it doesn't have a special case for HTTP error codes.

    Using `ILogger.LogError() won't show up on the graph, but you can still alert on it by creating a log alert on the requests table. Your 500 response should show up as success == "false" in the requests table in App Insights, even if Functions successfully completed its task. This is likely your best option if you would like to send a custom 500 response.

    requests  
    | where success == "False"   
    

    There is a similar question on Stack Overflow with more info: https://stackoverflow.com/questions/51646904/is-this-application-insight-azure-functions-bug-or-my-understanding-is-incorr?rq=1

    0 comments No comments

  2. Aron Kovacs 36 Reputation points
    2021-10-12T07:32:41.827+00:00

    Given we throw an exception in the function, is there a way how the error message of the exception is returned to the client? Is there a configuration setting somewhere? Currently, the client gets only 500 without anything else

    Your proposal unfortunately would always result in an empty result set if we handle the exception in order to return a more meaningful error to the client.

    0 comments No comments

  3. Samara Soucy 76 Reputation points
    2021-10-12T22:11:38.477+00:00

    I'm a bit confused as to what you mean by empty result set. There is no setting to change this default behavior.

    Let's say I have 2 functions, one where I catch the error, log it and return a custom response, and the other I let the error bubble up.

    public static IActionResult Run(HttpRequest req, ILogger log)  
    {  
        log.LogInformation("C# HTTP trigger function processed a request.");  
      
        try {  
            throw new Exception("caught exception");  
      
        } catch (Exception e){  
            log.LogError(e, "Bad request");  
      
            return new ObjectResult("There was an error") {StatusCode = 500};  
        }  
      
        return new OkObjectResult("OK Response");  
    }  
      
    public static async Task<IActionResult> Run(HttpRequest req, ILogger log)  
    {  
        log.LogInformation("C# HTTP trigger function processed a request.");  
      
        throw new Exception("uncaught exception");  
      
        return new OkObjectResult("OK Response");  
    }  
    

    When I catch the exception I do have the option of returning a custom message:

    139908-image.png

    As I mentioned, the function will count this as a success since it successfully returned a value to the output binding:

    139899-image.png

    And it is indeed missing from the default error graph:

    139992-image.png

    However, because of the log.LogError() call the stack trace and related information is retained and the request is marked as failed in App Insights.

    139880-image.png

    I can then use that query to create appropriate alert rules while still returning a custom response:

    139947-image.png