Best practices - throwing exceptions from a Web Se

2020-07-20 03:39发布

We have an ASMX web service which we invoke from our ASP.NET application using ajax (jQuery).

A typical example from our web methods would be something like:

[WebMethod]
public void DoSomething(BusinessObject myParameter)
{

    try
    {
       BL.DoSomethingWithParam(myParameter);
    }
    catch(Exception ex)
    { 
        //logic to log the actual exception goes here
        //and then we throw a more user-friendly error as so:
        throw new Exception("Unable to perform action such an such");
    }
}

On the client-side we would have something like this:

$.ajax({
   type: "POST",
   url: "WebService.asmx/DoSomething",
   data: "{}",
   contentType: "application/json; charset=utf-8",
   dataType: "json",
   success: function(result) {
      //do something with result.d
    },
   error: function(xhr, ajaxOptions, thrownError){ 
      alert($.parseJSON(xhr.Response.Text).Message);
   }
});

There are several problems with above approach, which I want to fix:

  1. When we test our application locally on our boxes, Internet Explorer displays the actual error message we throw on the throw new Exception line on our web method (In the case of the example code provided: "Unable to perform action such and such") BUT when we deploy to the stage environment and test remotely; it no longer displays the error we throw, but rather this: "There has been an error processing your request."
  2. On Firefox (we didn't test more browsers), it doesn't display anything at all but Firebug shows a HTTP 500 error being thrown.

In conclusion we are not handling this appropriately, so my questions are:

  1. What's the best way to communicate these errors to the client side and have consistent behavior amongst all browsers, both, when testing locally and remotely?
  2. Why doesn't IE break the same way Firefox does? Granted, testing remotely IE sort of breaks too, by not showing the real error message and replacing it for the generic There has been an error processing your request but why doesn't Firefox do the same?
  3. Considering the fact that this web service will also be consumed by other Java Web apps within the company, what's the best way to maintain interoperability with these apps? How can we still throw these exceptions on our web methods and have the Java app be able to catch them and handle them appropriately?

One alternative we implemented -for now, we are still in development phase- is just to return a string from our web methods when an error occurs but this is really an ugly hack/inelegant way to do this.

Note: Don't ask me where is the "There has been an error processing your request" message coming from. I don't have the faintest idea. We don't have anything in our code that would return that message.

1条回答
小情绪 Triste *
2楼-- · 2020-07-20 03:56

I don't know that a "correct" way has yet emerged due to the fact that how web services are being utilized is changing so rapidly and, ultimately, any client being constructed to consume the service is capable of handling whatever method you choose. I have no doubt that ultimately one will be devised but for now it's up to you.

That being said try to avoid some of the more common pitfalls I've seen in the past.

  1. Lack of Consistency: If your web service has multiple methods devise a way that they all may communicate errors in the same fashion to make your methods easier to consume. Personally I prefer following in the footsteps of protocol stacks and using some sort of consistent header. Build your resulting messages with a common header so that the same logic may be used throughout the client's code to determine if the method call was successful.
  2. No Support For Multiple Error Messages: Sometimes multiple failures occurred. Blinding the client to the secondary error can be a nuisance and slow down debugging attempts.
  3. Lack of Identification for Error Messages: If the error is the result of a particular field being invalid allow the client to programmatically identify which field is the culprit based on information you provide.

The approach I generally start with these days looks something like this:

{
    Success: bool,
    Errors[]: {
        Id: string,
        Source: string,
        Message: string
    },
    Message: { *Method specific structure* }
}
查看更多
登录 后发表回答