Section 10.1. Error Handling


10.1. Error Handling

Up to now, when working with web services, we expected our remote calls to work all the time, or to time out. However, the fact that the web service could throw an exception has not yet been considered.

When using web services from remote servers (which here means servers residing on another domain), developers often do not include exception-handling code. One reason is that a web service can be implemented with any technology, and every technology has its own way of running exceptions; some do not run exceptions at all.

However in the case of Atlas and Ajax, using web services is a bit different. We cannot directly use a remote service, since the security model forbids us to do soby default, JavaScript and the XMLHttpRequest object allow access only to URIs that reside within the same domain as the current page. When you work with Atlas, you are, therefore, calling a web service that is in the same domain, meaning that it is a web service based on .NET technology (or 187ased on WCF, the new Windows Communication Foundation). As a consequence, you know which exception model is used.

Atlas allows you to access in JavaScript code the exceptions thrown by a web service. To demonstrate this, let's write a simple math service that divides two numbers. You have probably already guessed where this is leading: if the user tries to trigger a divide by zero exception, we throw DivideByZeroException. Example 10-1 shows the code for a web service (MathService.asmx) that throws this exception.

Example 10-1. A web service that throws an exception

 MathService.asmx <%@ WebService Language="C#"  %> using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; [WebService(Namespace = "http://hauser-wenz.de/atlas/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class MathService  : System.Web.Services.WebService {     [WebMethod]     public float DivideNumbers(int a, int b) {       if (b == 0) {         throw new DivideByZeroException!();       } else {         return (float)a / b;       }     } } 

Now, let's assemble a page that calls this web service. We need two input fields in which to enter the values we would like to divide. We also need two output containers: one for the result of the division and one for eventual error messages. A button then calls the client-side function, which, in turn, calls the web service. Here's the markup for the page:

 <nobr>   <input type="text"  name="a" size="2" />   :   <input type="text"  name="b" size="2" />   =   <span  style="width: 50px;" /> </nobr> <br /> <input type="button" value="Divide Numbers" onclick="callService(this.form);" /> <br /> <div  style="width: 600px; height: 300px;"> </div> 

As for server controls on the page, we need two: the ScriptManager element and, embedded into it, the reference to the web service we want to use.

 <atlas:ScriptManager  runat="server">   <Services>     <atlas:ServiceReference Path="MathService.asmx" />   </Services> </atlas:ScriptManager> 

Now when you call the web service, you can use the automatically generated proxy object MathService. Remember the parameters when calling a web method: first the parameter(s) of the web method, then callback functions for call completion and call timeout.

However, this time we submit one more parameter to the DivideNumbers() method. After callback references to functions to handle call completion and timeout errors, we provide another callback. This is executed when an error occurs:

 function callService(f) {   document.getElementById("c").innerHTML = "";   MathService.DivideNumbers(     parseInt(f.elements["a"].value),     parseInt(f.elements["b"].value),     callComplete,     callTimeout,     callError); } 

This error-handling function gets an error object that contains three methods:


get_exceptionType()

Retrieves the type of the exception


get_message()

Retrieves the error message of the exception


get_stackTrace()

Retrieves the stack trace of the error

Here is JavaScript code that outputs this information in the <div> that we specifically created for receiving it:

Atlas Error Handling

Exceptions thrown by the ASP.NET server code can be shown via Atlas, as well. The <ErrorTemplate> subelement of the ScriptManager control provides a template that is used when an exception is thrown (this is especially convenient when using UpdatePanel controls, see Chapter 1). Here is how the markup can look:

 <atlas:ScriptManager  runat="server">   <ErrorTemplate>     Something went wrong.     We apologize for the inconvenience.   </ErrorTemplate> </atlas:ScriptManager> 

Using the OnPageError property of the ScriptManger, you can also call a method on the page when an error occurs.


 function callError(result) {   document.getElementById("output").innerHTML =     "<b>" +     result.get_exceptionType() +     "</b>: " +     result.get_message() +     "<br />" +     result.get_stackTrace(); } 

The rest of the example is straightforward. When the call to the web service completes successfully, output the result of the division in the <span> element. Example 10-2 shows the complete code for the page.

Example 10-2. A page that displays exceptions thrown by MathService

 Error.aspx <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">   <title>Atlas</title>   <script language="Javascript" type="text/javascript">   function callService(f) {     document.getElementById("c").innerHTML = "";     document.getElementById("output").innerHTML = "";     MathService.DivideNumbers(       parseInt(f.elements["a"].value),       parseInt(f.elements["b"].value),       callComplete,       callTimeout,       callError);   }   function callComplete(result) {     document.getElementById("c").innerHTML = result;   }   function callTimeout(result) {     window.alert("Error! " + result);   }   function callError(result) {     document.getElementById("output").innerHTML =       "<b>" +       result.get_exceptionType() +       "</b>: " +       result.get_message() +       "<br />" +       result.get_stackTrace();   }   </script> </head> <body>   <form  runat="server">     <atlas:ScriptManager  runat="server">       <Services>         <atlas:ServiceReference Path="MathService.asmx" />       </Services>     </atlas:ScriptManager>     <div>       <nobr>         <input type="text"  name="a" size="2" />         :         <input type="text"  name="b" size="2" />         =         <span  style="width: 50px;"></span>       </nobr>       <br />       <input type="button" value="Divide Numbers" onclick="callService(this.form);" />       <br />       <div  style="width: 600px; height: 300px;">       </div>     </div>   </form> </body> </html> 

Now when you divide 6 by 7, you get, as expected, 0.8571429. If however, you try to divide 6 by 0, the web service throws an exception, as expected. Figure 10-1 shows the output, including a short stack trace.

Figure 10-1. Information about the exception is shown





Programming Atlas
Programming Atlas
ISBN: 0596526725
EAN: 2147483647
Year: 2006
Pages: 146

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net