Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handlings exceptions on the server, customising the fail argument on the client

Tags:

signalr

I'm hoping to be able to customise the error objects that are passed to the client if an exception occurs on the server.

I'm using the 'then' function on the client to handle success and failure:

hub.server.login(username, password).then(function(result) {
    // use 'result'
}, function(error) {
    // use 'error'
});

If the login succeeds, 'result' is the return value of the Login method on the server. If the login fails, I throw an exception of 'CustomException'. This is an exception with a 'Code' property.

if (!IsValidLogin(username, password))
    throw new CustomException { Code: "BADLOGIN", Message: "Invalid login details" };

If I have detailed exceptions enabled, the 'error' argument on the client is 'Invalid login details' - the Message property of the exception.

Is there any way I can selectively change the error result from a string to a complex object? i.e. if 'CustomException' is thrown in a hub method, return a {Code:[...], Message:[...]} object for the client-side fail handler?

This should demonstrate what I'd like to see on the client:

hub.server.login(username, password).then(function(userInfo) {
    alert("Hello " + userInfo.Name);
}, function(err) {
    if (err.Code === "BADLOGIN.USERNAME")
        alert("Unrecognised user name");
    else if (err.Code === "BADLOGIN.PASSWORD");
        alert("Invalid password");
    else
        alert("Unknown error: " + err.Message);
});

(Note the 'Code' and 'Message' properties on 'err').

like image 818
Barguast Avatar asked Oct 22 '22 10:10

Barguast


1 Answers

When you call MapHubs with EnabledDetailedErrors set to true as follows:

RouteTable.Routes.MapHubs(new HubConfiguration { EnableDetailedErrors = true });

you will receive your Exception's Message string as the parameter to your fail handler.

I see that you have already figured this out, but I'm including the server side code to enable detailed errors for anyone else who might find this question later.

Unfortunately there is no easy way to send a complex object to the fail handler.

You could do something like this though:

if (!IsValidUsername(username))
{
    var customEx = new CustomException { Code: "BADLOGIN.USERNAME", Message: "Invalid login details" };
    throw new Exception(JsonConvert.SerializeObject(customEx));
}
if (!IsValidPassword(username, password))
{
    var customEx = new CustomException { Code: "BADLOGIN.PASSWORD", Message: "Invalid login details" };
    throw new Exception(JsonConvert.SerializeObject(customEx));
}

Then on the client:

hub.server.login(username, password).then(function(userInfo) {
    alert("Hello " + userInfo.Name);
}, function(errJson) {
    var err = JSON.parse(errJson);
    if (err.Code === "BADLOGIN.USERNAME")
        alert("Unrecognised user name");
    else if (err.Code === "BADLOGIN.PASSWORD");
        alert("Invalid password");
    else
        alert("Unknown error: " + err.Message);
});

I know this is ugly, but it should work.

like image 125
halter73 Avatar answered Nov 08 '22 00:11

halter73