C# 从Azure函数HttpTrigger返回错误详细信息

C# 从Azure函数HttpTrigger返回错误详细信息,c#,.net,azure-functions,C#,.net,Azure Functions,我已经创建了一个带有HTTP触发器的Azure函数。我想将详细的错误信息返回给呼叫者。对于未捕获的异常,是否有一种处理方法?奇怪的是,Azure函数在VisualStudio中运行时确实返回了详细的错误信息,但在部署时却没有返回 [FunctionName("MyAzureFunction")] public static async Task<HttpResponseMessage> RunAsync( [HttpTrigger(AuthorizationLevel.Fun

我已经创建了一个带有HTTP触发器的Azure函数。我想将详细的错误信息返回给呼叫者。对于未捕获的异常,是否有一种处理方法?奇怪的是,Azure函数在VisualStudio中运行时确实返回了详细的错误信息,但在部署时却没有返回

[FunctionName("MyAzureFunction")]
public static async Task<HttpResponseMessage> RunAsync(
    [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage httpRequest,
    TraceWriter traceWriter,
    CancellationToken cancellationToken)
{
    try
    {                
        var response = await ProcessAsync(request, cancellationToken);

        return httpRequest.CreateResponse(HttpStatusCode.OK, response);
    }
    catch (ArgumentException ex)
    {
        traceWriter.LogWarning($"Argument error: {ex}");
        return httpRequest.CreateResponse(HttpStatusCode.BadRequest, ex.Message);
    }
    catch (Exception ex)
    {
        traceWriter.LogError($"Error: {ex}");
        throw;
    }
}
[FunctionName(“MyAzureFunction”)]
公共静态异步任务RunAsync(
[HttpTrigger(AuthorizationLevel.Function,“post”,Route=null)]HttpRequestMessage httpRequest,
TraceWriter TraceWriter,
取消令牌(取消令牌)
{
尝试
{                
var response=await ProcessAsync(请求、取消令牌);
返回httpRequest.CreateResponse(HttpStatusCode.OK,response);
}
捕获(参数异常)
{
LogWarning($“参数错误:{ex}”);
返回httpRequest.CreateResponse(HttpStatusCode.BadRequest,ex.Message);
}
捕获(例外情况除外)
{
LogError($“Error:{ex}”);
投掷;
}
}

通常,从安全性和其他角度来看,将异常详细信息返回给外部调用方被认为是不好的做法。因此,默认情况下阻止此信息是有意义的

我将替换
抛出语句,其中一个返回手动格式化的错误。如果您同意向调用者公开异常消息,那么只需

return httpRequest.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);

如果调用方是外部的,我也不会这样做:相反,返回一条通用错误消息,然后依靠日志进行调试。

作为请求和响应的最新解决方案,最好分别使用HttpRequest和IActionResult,而不是HttpRequestMessage和HttpResponseMessage。此外,您可以使用遥测客户端手动处理失败的操作,而无需抛出。如果请求不正确,此代码将在应用程序上创建失败的操作

[FunctionName(nameof(MyAzureFunction))]
public static async Task<IActionResult> RunAsync(
    [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest httpRequest,
    ILogger logger,
    CancellationToken cancellationToken)
{
    using var operation = _telemetryClient.StartOperation(new RequestTelemetry
    {
        Name = $"Execute MyAzureFunction"
    });

    try
    {
        var response = await ProcessAsync(request, cancellationToken);

        // NOTE: You can alternatively handle the response in a layer before and use a generic object result here: 
        //return new ObjectResult(response)
        //{
        //    StatusCode = response.Status
        //};

        return new OkObjectResult(result);
    }
    catch (ArgumentException ex)
    {
        logger.LogWarning(ex, $"Argument error: {ex.Message}");

        // NOTE: Without this, the original request would be considered as successful, although the Http response code would be 400
        operation.Telemetry.Success = false;
        operation.Telemetry.ResponseCode = HttpStatusCode.BadRequest.ToString();

        return new BadRequestObjectResult(ex.Message);
    }
    catch (Exception ex)
    {
        logger.LogError($"Error: {ex}");
        throw;
    }
}
[FunctionName(nameof(MyAzureFunction))]
公共静态异步任务RunAsync(
[HttpTrigger(AuthorizationLevel.Function,“post”,Route=null)]HttpRequest HttpRequest,
ILogger记录器,
取消令牌(取消令牌)
{
使用var操作=_telemetryClient.StartOperation(新请求遥测
{
名称=$“执行MyAzureFunction”
});
尝试
{
var response=await ProcessAsync(请求、取消令牌);
//注意:您也可以在之前处理层中的响应,并在此处使用通用对象结果:
//返回新的ObjectResult(响应)
//{
//StatusCode=响应。状态
//};
返回新的OkObjectResult(结果);
}
捕获(参数异常)
{
logger.LogWarning(例如,$“参数错误:{ex.Message}”);
//注意:如果没有此选项,原始请求将被视为成功,尽管Http响应代码为400
operation.Telemetry.Success=false;
operation.Telemetry.ResponseCode=HttpStatusCode.BadRequest.ToString();
返回新的BadRequestObjectResult(例如消息);
}
捕获(例外情况除外)
{
logger.LogError($“Error:{ex}”);
投掷;
}
}