2014-01-07 9 views
15

У меня есть простой метод контроллера APIКак получить правильную трассировку стека для исключений в действиях async для Web API 2?

public async Task<Models.Timesheet> GetByDate(DateTime date, string user = null) 
{ 
    throw new InvalidOperationException(); 
} 

Теперь проблема в том, что стек исключение трассировки я получаю либо в моем пользовательского действия фильтра или просто установив IncludeErrorDetailPolicy.Always подобно этому

System.InvalidOperationException: Operation is not valid due to the current state of the object. 
    at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__1.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Web.Http.ApiController.<InvokeActionWithExceptionFilters>d__1.MoveNext() 

Он используется чтобы быть лучше с Web API v1. После обновления до v2 трассировки стека в значительной степени непригодны - ожидается, что при асинхронном/ожидании трассировки стека не будут такими, какими они когда-то были, но в этом случае вся трассировка стека не содержит намека на даже класс, который не смогли. Есть ли что-то, что можно настроить в веб-API для смягчения проблемы?

ответ

7

Это было исправлено в WebAPI 2.1 (версия сборки 5.1.1)

Следуйте эти инструкции, чтобы обновить его до последней версии: https://www.nuget.org/packages/Microsoft.AspNet.WebApi

+0

Это не дает ответа на вопрос. Чтобы критиковать или просить разъяснения у автора, оставьте комментарий ниже их сообщения. –

+0

Если это правила, я последую за ними в будущем. Однако рассмотрим это - у меня нет критики для автора, это единственное решение в WebApi 5.0.0, но теперь есть лучшее решение - обновление до WebApi v5.1.1 –

+5

Это действительно лучший ответ, это ошибка в структуре и лучший способ исправить это - обновить. –

1

Я считаю, что трассировки стека улучшены на .NET 4.5.1 при работе в Windows 8.1/Server 2012 R2.

В качестве альтернативы у меня есть "Async Diagnostics" NuGet package, которые вы можете установить в свой проект. Затем добавьте следующую строку:

[assembly: AsyncDiagnosticAspect] 

И вы можете использовать метод ToAsyncDiagnosticString расширения на Exception типа. ToAsyncDiagnosticString содержит всю информацию от ToString, а затем добавляет «логический стек». Дополнительная документация (и источник) on GitHub.

Обратите внимание, что поддержка частичного доверия отсутствует, и это лучше всего работает в сборках Debug.

4

Итак, после того, как я задал вопрос, я получил правильную мотивацию, чтобы правильно копать код веб-API, чтобы найти проблему. Кажется, что виновником является ActionFilterAttribute.CallOnActionExecutedAsync метод, который делает что-то вроде этого (переоформленную, а не фактический код):

try 
{ 
    await previous(); 
} 
catch(Exception ex) 
{ 
    exception = ex; 
} 

var context = new HttpActionExecutedContext(actionContext, exception); 
this.OnActionExecuted(context); 
if (context.Response == null && context.Exception != null) 
    throw context.Exception; 

Так получилось, что первый фильтр на самом деле получает правильный след стека. Но тогда он просто уходит и перерисовывает исключение, тем самым теряя исходную трассировку стека.

Это заставило меня понять, что вместо получения ExceptionFilterAttribute мне нужно получить от ActionFilterAttribute, так как первые всегда называются последними. К сожалению, мне также необходимо убедиться, что мой фильтр исключений работает первым, но это не встроенный веб-API (see this question для правильного решения для этого).

Мое быстрое решение заключалось в том, чтобы убедиться, что все фильтры, которые у меня есть в приложении (у меня есть только несколько), получены из моего настраиваемого фильтра исключений (и вызывают base.OnActionExecuted()), поэтому каждый отдельный фильтр будет проверять исключение и выполнять что-то вроде это:

public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 
{ 
    if (actionExecutedContext.Exception == null) 
     return; 

    WriteLog(actionExecutedContext.Exception); 

    actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(
     System.Net.HttpStatusCode.InternalServerError, 
     actionExecutedContext.Exception.Message, 
     actionExecutedContext.Exception); 

    actionExecutedContext.Exception = null; 
} 

с помощью этого обходного я получил правильный стек следы как к бревну и пользователю, если сведения об ошибке включены.

+0

Пожалуйста открытое это как ошибка, так что команда WebAPI осознает проблема. –

+2

Just FYI ... post Web API 2, эта проблема исправлена, и вы увидите трассировки стека, как ожидалось. –

 Смежные вопросы

  • Нет связанных вопросов^_^