我正在尝试使用自定义IExceptionHandler
来使用我的Azure功能(C#类库)。我的想法是拥有自己的异常处理程序,用于包含我自己的内存中跟踪日志的意外异常;澄清一下,我做希望将这些发送到客户端浏览器并显示给用户。
详细信息如下。
使用这个简单的自定义异常处理程序:
public sealed class CustomExceptionHandler : ExceptionHandler
{
public override void Handle(ExceptionHandlerContext context)
{
context.Result = new ResponseMessageResult(
context.Request.CreateErrorResponse(HttpStatusCode.BadRequest,
"custom message string"));
}
}
我试图安装它:
[FunctionName("Function1")]
public static HttpResponseMessage Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "works")]
HttpRequestMessage req)
{
req.GetConfiguration().Services.Replace(typeof(IExceptionHandler),
new CustomExceptionHandler());
throw new Exception("unexpected exception");
}
但部署后,我只是收到通用的“操作失败”错误消息(例如,从Chrome格式化XML格式):
<ApiErrorModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Azure.WebJobs.Script.WebHost.Models">
<Arguments xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" i:nil="true"/>
<ErrorCode>0</ErrorCode>
<ErrorDetails i:nil="true"/>
<Id>dec07825-cf4e-49cc-a80e-bef0dbd01ba0</Id>
<Message>An error has occurred. For more information, please check the logs for error ID dec07825-cf4e-49cc-a80e-bef0dbd01ba0</Message>
<RequestId>51df1fec-c1c2-4635-b82c-b00d179d2e50</RequestId>
<StatusCode>InternalServerError</StatusCode>
</ApiErrorModel>
如果我在AF用户界面中打开Diagnostic Logs -> Detailed error messages
并尝试确保始终写入详细的错误消息:
[FunctionName("Function1")]
public static HttpResponseMessage Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "works")]
HttpRequestMessage req)
{
req.GetRequestContext().IncludeErrorDetail = true;
req.GetRequestContext().IsLocal = true;
req.GetConfiguration().Services.Replace(typeof(IExceptionHandler),
new CustomExceptionHandler());
throw new Exception("unexpected exception");
}
然后我得到了异常细节,但显然仍然由内置异常处理程序(从Chrome格式化XML)处理:
<ApiErrorModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Azure.WebJobs.Script.WebHost.Models">
<Arguments xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" i:nil="true"/>
<ErrorCode>0</ErrorCode>
<ErrorDetails>Microsoft.Azure.WebJobs.Host.FunctionInvocationException : Exception while executing function: Function1 ---> System.Exception : unexpected exception at ...</ErrorDetails>
<Id>5e752375-002b-4ab7-a348-20edad64a3fe</Id>
<Message>Exception while executing function: Function1 -> unexpected exception</Message>
<RequestId>b6611456-f3f1-4591-97e4-920dae59b5ff</RequestId>
<StatusCode>InternalServerError</StatusCode>
</ApiErrorModel>
所以这是暴露堆栈跟踪和异常消息,但我没有内存中的跟踪日志。
我想要做的是为自己创建意外异常的响应消息。例如,这是我的自定义错误响应对于预期的异常(来自Postman的JSON格式):
{
"message": "An error has occurred.",
"exceptionMessage": "Could not find package `nito.bob`",
"exceptionType": "Common.ExpectedException",
"stackTrace": " at ...",
"log": [
"Received request for jsonVersion=4, packageId=`nito.bob`, packageVersion=``, targetFramework=``",
"Looking up latest package version for `nito.bob`",
"No non-prerelease package version found for `nito.bob`; looking up latest prerelease package version",
"No package version found for `nito.bob`",
"Returning 404: Could not find package `nito.bob`"
],
"requestId": "b2df08cb-1071-4e47-bd24-bf74152e4b2a"
}
这只是我使用HttpError
和log
进行扩充的基本requestId
格式化异常(包含详细信息)。由于这是一个预期的例外,这不是在IExceptionHandler
中完成的;我刚刚返回HttpResponseMessage
。
有趣的部分:我的自定义IExceptionHandler
在本地托管AF时正常。它只是不起作用when deployed。如果我使用the code并在本地运行它,我会收到我期望的响应(来自Postman的JSON格式):
{
"Message": "custom message string"
}
对我不起作用的替代方法:
Exception
并返回HttpRequestMessage.CreateErrorResponse
。我已经为预期的异常做了这个,这很好。这不是意外异常的好解决方案,因为我希望功能执行明确标记为“失败”。返回HttpResponseMessage
(即使有500状态代码)被AF运行时视为“成功”,并且在仪表板或日志中不显示为“失败”(或者可能是App Insights,尽管我还没有' t明确检查过)。