2012-11-27 16 views
14

Używam SignalR hub w mojej aplikacji MVC4. Dodałem ELMAH do obsługi wszystkich błędów. Problem polega na tym, że błędy, które zdarzają się w centrum, nie są rejestrowane w aksjomie ELMAH. Czy istnieje sposób, aby to skonfigurować?Jak skonfigurować ELMAH z SignalR

Odpowiedz

9

Musisz dodać HubPipelineModule, a także upewnić się, że ustawiłeś ApplicationName w Twoim elemencie errorLog, W przeciwnym razie Elmah nie będzie w stanie zarejestrować błędu, ponieważ nie będzie miał HttpContext lub AppName do logowania do .

<errorLog type="Elmah.SqlErrorLog, Elmah" applicationName="MyAppName" connectionStringName="myConnString" /> 

HubPipelineModule code I've used jest następujący:

public class ElmahPipelineModule : HubPipelineModule 
{ 
    private static bool RaiseErrorSignal(Exception e) 
    { 
     var context = HttpContext.Current; 
     if (context == null) 
      return false; 
     var signal = ErrorSignal.FromContext(context); 
     if (signal == null) 
      return false; 
     signal.Raise(e, context); 
     return true; 
    } 

    private static void LogException(Exception e, IHubIncomingInvokerContext invokerContext) 
    { 
     var context = HttpContext.Current; 
     ErrorLog el = ErrorLog.GetDefault(context); 
     el.Log(new Error(e)); 
    } 

    protected override void OnIncomingError(Exception ex, IHubIncomingInvokerContext context) 
    { 
     var exception = ex; 
     if (ex is TargetInvocationException) 
     { 
      exception = ex.InnerException; 
     } 
     else if (ex is AggregateException) 
     { 
      exception = ex.InnerException; 
     } 

     if (!RaiseErrorSignal(exception)) 
      LogException(exception, context); 
    } 
} 

Upewnij się dodać moduł do rurociągu piasta:

GlobalHost.HubPipeline.AddModule(new ElmahPipelineModule()); 

EDIT

SignalR 2+

Zauważyłem, że żaden z moich wyjątków SignalR nie był rejestrowany w ostatnim projekcie, nad którym pracowałem, i odkryłem, że wyjątek ArgumentNullException jest generowany podczas próby pobrania ErrorSignal z bieżącego kontekstu. Następująca metoda prawidłowo radzi sobie z tym wyjątkiem, aby ponownie rejestrować błędy SignalR.

private static bool RaiseErrorSignal(Exception e) 
{ 
    var context = HttpContext.Current; 
    if (context == null) 
     return false; 

    try 
    { 
     var signal = ErrorSignal.FromCurrentContext(); 
     if (signal == null) 
      return false; 
     signal.Raise(e, context); 
     return true; 
    } 
    catch (ArgumentNullException) 
    { 
     return false; 
    } 
} 
+1

Dla każdego, kto utknął na ostatnim kroku, dodaj ostatnią linię do klasy RegisterHubs. Na przykład: 'public static void Start() {RouteTable.Routes.MapHubs(); GlobalHost.HubPipeline.AddModule (nowy Shopperscape.Web.API.ElmahPipelineModule()); } ' – Chris

+0

@Chris Czy to działa dla SignalR 1.x? –

+1

@Giles - ten kod jest dla SignalR 1 – damienc88