Callback Exception Handling

  • 6 minutes to read

Typically, when a web component sends a callback that is processed on the server side and an unhandled server error occurs, the web application becomes unresponsive to the end-user (i.e., it crashes or hangs in the client’s browser). DevExpress ASP.NET components (Web Forms controls and MVC extensions) implement a built-in callback error-handling mechanism so that the application remains responsive.

ASPxHttpHandlerModule includes an error-handling mechanism to catch unhandled server exceptions while callbacks are processed. The module generates and sends a response that contains exception-related information - so that the application stays responsive.

By default, error messages are displayed in a browser based on the web component that initiated the callback as follows.

  • For an AJAX-enabled DevExpress web component - error information is shown within the component’s UI element;
  • For an external components - error details are displayed within a popup message box.

The error message sent to a remote client depends on the mode attribute setting defined in Web.config‘s <customErrors> section.

Displaying Message Text for Callback Errors

If an unhandled exception occurs while a DevExpress web component’s callback is processed on the server side, ASPxHttpHandlerModule automatically catches the exception and passes an error message to the client. This message may contain details about the exception or a generic error message. The message displayed depends on the mode attribute setting within the Web.config file’s <customErrors> section. This attribute affects message text in the following manner.

  • On - Generic (custom) error text is shown to remote clients and to the local host. This text can be localized, and is defined by the ASPxperienceStringId.CallbackGenericErrorText constant.
  • Off - Detailed ASP.NET errors are shown to remote clients and to the local host.
  • RemoteOnly - Generic (custom) error text is shown only to remote clients, and detailed ASP.NET errors are displayed on the local host.

Regardless of the customErrors section’s mode setting, you can use one of the following approaches to modify the error message to be sent to the client.

  • Component Level
    Handle a DevExpress component’s CustomErrorText event, if any. Some DevExpress MVC extensions provide this event (such as FileManager’s FileManagerSettings.CustomErrorText and Scheduler’s SchedulerSettings.CustomErrorText) .

    In the event handler, use the e.ErrorText property to define error text. Note that the initial value passed to this event depends on the <customErrors>‘s mode setting. Within the event, you can access the source error (and its error message) via the e.Exception property.

  • Application Level
    Alternatively, you can use the static ASPxWebControl.SetCallbackErrorMessage method to handle errors at the application level.

    Call this method in handlers of the Application_Error and ASPxWebControl.CallbackError events in Global.asax. Within these handlers, use the HttpContext.Current.Server.GetLastError method to access the source error.

    View Example: How to handle app level errors occurred inside ASP.NET MVC controls during callbacks

    //Generate your own exception type
    @Html.DevExpress().GridView(settings => {
        settings.Name = "GridView";
        ...
        settings.InitNewRow = (sender, e) => {
            //throw new Exception("A new exception.");
            throw new CustomExceptions.MyException("New row initialization is disabled. Please log in as administrator.");
        };
        ...
    }).Bind(Model).GetHtml()
    
    //Change error text in CallbackError event handler using the SetCallbackErrorMessage method 
    void Application_Start(object sender, EventArgs e){
        DevExpress.Web.ASPxWebControl.CallbackError += Callback_Error;
    }
    
    protected void Callback_Error(object sender, EventArgs e) {
        var exception = HttpContext.Current.Server.GetLastError();
        //Check exception type and specify error text for your exception
        if(exception is CustomExceptions.MyException) {
            DevExpress.Web.ASPxWebControl.SetCallbackErrorMessage(exception.Message);
        }
    }
    

Handling Callback Exceptions

View Example: How to handle app level errors occurred inside ASP.NET MVC controls during callbacks

On the Client Side

A DevExpress ASP.NET Ajax-enabled component automatically catches server exceptions that occur within its server-side event handler, and passes corresponding error information to the client for processing. On the client side, use the component’s CallbackError client event to process the error at the component level, or handle the MVCxGlobalEvents extension’s MVCxClientGlobalEvents.CallbackError client event to process the error globally (across all DevExpress MVC web component).

Handle either of these client events to perform specific client-side actions, such as to display explanatory text or an image related to the error.

This example demonstrates how to use the Spreadsheet ‘s CallbackError client event to process a server error.

@Html.DevExpress().Spreadsheet(settings => {
    settings.Name = "Spreadsheet";
    settings.ClientSideEvents.CallbackError = "OnCallbackError";
    settings.PreRender = (s, e) => {
        // ...
        throw new Exception("A new exception.");
    };
}).GetHtml()
function OnCallbackError(s, e) {
    e.handled = true;
    alert('The CallbackError event is raised: ' + e.message;
}

On the Server Side

You can use the static ASPxWebControl.CallbackError server event to delegate callback exception handling to the Application_Error event handler (via the web application project’s Global.asax file), so that it handles all application-level errors (e.g., to log information on all errors). In the Global.asax file, add the following code to the Application_Start event handler.

void Application_Start(object sender, EventArgs e) { 
    // Assign Application_Error as a callback error handler for DevExpress web controls
    ASPxWebControl.CallbackError += new EventHandler(Application_Error); 
} 

Use the following code within the Application_Error event handler to obtain and log exception details:

void Application_Error(object sender, EventArgs e) { 
    // ... 
    // Use HttpContext.Current to get a Web request processing helper 
    HttpServerUtility server = HttpContext.Current.Server; 
    Exception exception = server.GetLastError(); 
    // Log an exception 
    AddToLog(exception.Message, exception.StackTrace); 
}

Response Redirection on Callback Exceptions

When an unhandled exception occurs during server-side callback processing, ASPxHttpHandlerModule prevents an application from becoming unresponsive by sending a specific response to the client. Specify the required page name in the Web.config file’s callbackErrorRedirectUrl option to redirect the response to a page that displays error information – as shown below.

<configuration>
  ...
  <devExpress>
    ...
    <errors callbackErrorRedirectUrl="/Errors/Error.cshtml" />
  </devExpress>
</configuration>

Note that the callbackErrorRedirectUrl property value should contain the subdirectory name (if required) and use the following format: /subdir/Home/Error

Note

For MVC apllications, the callbackErrorRedirectUrl property value should contain a subdirectory name (“/{sub-directory}/Home/Error”) if the MVC application’s root URL meets the following conditions:

  • The URL is overridden by the IIS Web Server.
  • The URL contains a subdirectory (for example, “http://localhost/{sub-directory}”).

Typically, the page to which the response is redirected shows information about the server exception. Use the static ASPxWebControl.GetCallbackErrorMessage method while the page redirect is processed, to obtain exception-related information. For example, you can execute the code below on page load.

using DevExpress.Web.ASPxClasses;

public partial class Error : Page {
    protected void Page_Load(object sender, EventArgs e) {
        string errorMessage = ASPxWebControl.GetCallbackErrorMessage();
        Response.Output.Write(errorMessage);
    }
}