Asynchronous error handling change in ASP.NET AJAX 3.5

There is a subtle change in the .NET 3.5 release of the Microsoft Ajax Library that might catch some developers by surprise when handling asynchronous postback errors. The change can be found at the end of the endPostBack function of the PageRequestManager object. In the first release of the Ajax library, if an error was not handled on the client; an alert box was used to convey to the user the error message:

 

ASP.NET AJAX 1.0 (MicrosoftAjaxWebForms.debug.js):

   1: function Sys$WebForms$PageRequestManager$_endPostBack(error, response) {
   2:     this._processingRequest = false;
   3:  
   4:     this._request = null;
   5:     this._additionalInput = null;
   6:  
   7:     var handler = this._get_eventHandlerList().getHandler("endRequest");
   8:     var errorHandled = false;
   9:     if (handler) {
  10:         var eventArgs = new Sys.WebForms.EndRequestEventArgs(error, this._dataItems, response);
  11:         handler(this, eventArgs);
  12:         errorHandled = eventArgs.get_errorHandled();
  13:     }
  14:     this._dataItems = null;
  15:     if (error && !errorHandled) {
  16:         alert(error.message);
  17:     }
  18: }

 

The problem with this approach is that it was too intrusive to assume that the alert box would be the ideal behavior. Instead, it makes more sense for the error to be thrown to the client so that you can have more control of the outcome. Therefore, the change in ASP.NET 3.5 is to simply throw the error if it hasn't been handled.
 
 
ASP.NET AJAX in .NET 3.5 (MicrosoftAjaxWebForms.debug.js):
   1: function Sys$WebForms$PageRequestManager$_endPostBack(error, response) {
   2:     if (this._request === response.get_webRequest()) {
   3:         this._processingRequest = false;
   4:         this._additionalInput = null;
   5:         this._request = null;
   6:     }
   7:     var handler = this._get_eventHandlerList().getHandler("endRequest");
   8:     var errorHandled = false;
   9:     if (handler) {
  10:         var eventArgs = new Sys.WebForms.EndRequestEventArgs(error, this._dataItems, response);
  11:         handler(this, eventArgs);
  12:         errorHandled = eventArgs.get_errorHandled();
  13:     }
  14:     if (!this._processingRequest) {
  15:         this._dataItems = null;
  16:     }
  17:     if (error && !errorHandled) {
  18:         throw error;
  19:     }
  20: }

 

So what does this mean to code you've written for ASP.NET 2.0 that has been migrated to ASP.NET 3.5? Well, if you haven't handled the endRequest client-side event after an async postback then the user is now going to experience a runtime error, whereas they would have simply experienced an alert box with the error message before:

 

 

Here is a simple example of how to reproduce this behavior in ASP.NET 3.5:

HTML:

   1: <asp:ScriptManager ID="ScriptManager1" runat="server" />
   2: <div>
   3:     <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
   4:         <ContentTemplate>
   5:             <asp:Button ID="ThrowError" runat="server" OnClick="ThrowError_OnClick" Text="Throw Error" />
   6:         </ContentTemplate>
   7:     </asp:UpdatePanel>
   8: </div>

 

Code behind:

   1: protected void Page_Load(object sender, EventArgs e)
   2: {
   3:     ScriptManager sm = ScriptManager.GetCurrent(this.Page);
   4:     sm.AsyncPostBackError += new EventHandler<AsyncPostBackErrorEventArgs>(ScriptManager1_OnAsyncPostBackError);
   5:     sm.AllowCustomErrorsRedirect = false;
   6: }
   7:  
   8:  
   9: protected void ScriptManager1_OnAsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)
  10: {
  11:     ScriptManager.GetCurrent(this.Page).AsyncPostBackErrorMessage = "Please try that again.";
  12: }
  13:  
  14: protected void ThrowError_OnClick(object sender, EventArgs e)
  15: {
  16:     throw new InvalidOperationException("Throw error!");
  17: }

 

Lastly, here is an example of how to handle the endRequest event thrown by the PageRequestManager to avoid the runtime error:

   1: <script type="text/javascript">
   2:  
   3:     Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onEndRequest);
   4:     
   5:     function onEndRequest(sender, args) {
   6:         var error = args.get_error();
   7:         if (error != null) {
   8:  
   9:             // Set the error handled flag to avoid a runtime error
  10:             // reaching the user.
  11:             args.set_errorHandled(true);
  12:             
  13:             // Remove the error name from the message
  14:             var msg = error.message.replace("Sys.WebForms.PageRequestManagerServerErrorException: ", "");                                
  15:             alert(msg);                
  16:         }
  17:     }
  18:  
  19: </script>

 

In the example, the message name is removed so that the user will only view the intended postback error message set from the code-behind. But more importantly, is the ability to take control of how the error is handled with the handler for the endRequest event.

For a more in-depth example of client-side events during an async postback, check out this post: Client-side event viewer.

7 Comments

  • One Problem is that We Can't get the Stack trace of the error.
    I have asked it in the forum http://forums.asp.net/p/1287242/2476466.aspx
    but with no satisfiable reply

  • Thanks for this - very helpfull.

    If I wanted to put this into a Master page (and therefore only have to write the JavaScript once in my site), is that possible?
    I have tried but get an error.

    Thanks,

    Michael

  • Kamii,

    Like you suspected, it doesn't look like you can get the stack trace out of the error. You can always append it to the message like the forum post suggest but if that isn't something you want to do either because of the increase in payload, you might want to consider just adding a key to the payload that you can use as a lookup for the stack trace in your database (or error log repository).

    -David

  • I tried Ajax ASP.NET 3.5 error handling approach on sharepoint 2007, it does not work and ends with a Sys.ArgumentNullException. Please help!

  • Thanks so much! I have been looking for a simple solution in this issue for ages! Greetings from Berlin!

  • thanks - that was useful!! I recently upgraded my web project to include 3.5 version of .net and i was getting all my errors/exceptions in the status bar. followed your post and i have put the script code in my master page.. now, i am getting all my errors as messsage boxes now.. thanks again..

  • Thanks, it solved my problem

Comments have been disabled for this content.