Search code examples
c#asp.netasp.net-mvc-4signalrsignalr-hub

Customizing SignalR's error messages


I use the SignalR 1.0. When exception occurs on the server, the client gets a message like this

{"I":"0","E":"Exception of type 'System.Exception' was thrown.","T":" at METHODNAME in d:\PATH\TO\HUB.cs:line 227\r\n at METHODNAME in d:\PATH\TO\HUB.cs:line 51"}

But I want to make it more user-friendly. How to I can do it? I have read a suggestion to put all server methods into try-catch block. But I think that it is not a true-way.

I traced the Exception and found that the Exception was catched in the Microsoft.AspNet.SignalR.Hubs.HubDispatcher.Incoming method. But it is internal static method which I cannot customize.

In the ideal case I want to get ability to convert an exception to a valid response.


Solution

  • You can use a HubPipelineModule.

    For example:

    using System;
    using System.Threading.Tasks;
    using Microsoft.AspNet.SignalR.Hubs;
    
    public class MyHubPipelineModule : HubPipelineModule
    {
        protected override Func<IHubIncomingInvokerContext, Task<object>> BuildIncoming(Func<IHubIncomingInvokerContext, Task<object>> invoke)
        {
            return async context =>
            {
                try
                {
                    // This is responsible for invoking every server-side Hub method in your SignalR app.
                    return await invoke(context); 
                }
                catch (Exception e)
                {
                    // If a Hub method throws, have it return the error message instead.
                    return e.Message;
                }
            };
        }
    }
    

    Then in your Global.asax.cs:

    protected void Application_Start()
    {
        GlobalHost.HubPipeline.AddModule(new MyHubPipelineModule());
        //...
        RouteTable.Routes.MapHubs();
    }