How to handle exceptions in network apps (HTML)

This topic explains how to handle exceptions when using networking APIs in a Windows Store app written in JavaScript and HTML.

What you need to know

Technologies

Prerequisites

  • The following information applies to Windows Store apps that uses networking APIs to make remote connections. This topic applies to apps written in JavaScript and HTML for Windows 8.1, Windows Phone 8.1, or Windows Server 2012 R2.

    For more information on handling exceptions in Windows Store apps written in C++/XAML and apps using the .NET Framework 4.5 in C#, VB.NET, or managed C++ for Windows 8.1, Windows Phone 8.1, or Windows Server 2012 R2, see Handling exceptions in network apps.

Exceptions in network apps

When an exception occurs in an app, this indicates a significant problem or failure. Exceptions can occur for many reasons. Your code may have issues that may cause the exception. Other times, particularly using networking APIs, the exception can result from changes in network connectivity and other networking issues.

Reasons for exceptions when use networking APIs include the following:

  • Parameter validation errors
  • Name resolutions failures when looking up a hostname or URI
  • Loss of network connectivity
  • Network connection failures using sockets and HTTP client APIs
  • Network server or remote endpoint errors
  • Miscellaneous networking errors

Exceptions from network errors (loss of connectivity, connection failures, and HTTP server failures, for example) can happen at any time. These errors result in exceptions being thrown. If not handled by your app, an exception can cause your entire app to be terminated by the runtime.

You must write code to handle exceptions when you call most asynchronous network methods. Sometimes when an exception occurs, a network method can be retried to try and resolve the problem. Other times, your app may need to plan to continue without network connectivity using previously cached data.

Windows Runtime apps generally throw a single exception. Your exception handler can retrieve more detailed information on the cause of the exception to better understand the failure and make appropriate decisions.

JavaScript supports a method to access this more detailed information. An exception projects as an HRESULT value in Windows Runtime apps. The Winerror.h include file contains a very large list of possible HRESULT values that includes network errors.

The networking APIs support different methods for retrieving this detailed information on the cause of an exception.

  • A helper method that converts the HRESULT value from the exception to an enumeration value.
  • The raw method depending on the language used to retrieve the HRESULT value.

Exceptions in Windows.Networking.Sockets

The Windows.Networking.Sockets namespace has convenient helper methods and enumerations for handling errors when using sockets and WebSockets. This can be useful for handling specific network exceptions differently in your app.

An error encountered on DatagramSocket, StreamSocket, or StreamSocketListener operation is returned as an HRESULT value. The SocketError.GetStatus method is used to convert a network error from a socket operation to a SocketErrorStatus enumeration value. Most of the SocketErrorStatus enumeration values correspond to an error returned by the native Windows sockets operation. An app can filter on specific SocketErrorStatus enumeration values to modify app behavior depending on the cause of the exception.

An error encountered on a MessageWebSocket or StreamWebSocket operation is returned as an HRESULT value. The WebSocketError.GetStatus method is used to convert a network error from a WebSocket operation to a WebErrorStatus enumeration value. Most of the WebErrorStatus enumeration values correspond to an error returned by the native HTTP client operation. An app can filter on specific WebErrorStatus enumeration values to modify app behavior depending on the cause of the exception.

The following sample code shows how to filter on an exception using the WebErrorStatus enumeration.

var uri = new Uri("https://www.contoso.com");
var messageWebSocket = new Windows.Networking.Sockets.MessageWebSocket();


// Always catch network exceptions for async methods
messageWebSocket.ConnectAsync(uri).done(function () {
        // get completed
    }, onError);

function onError(reason) {
    // Details in reason.message and reason.number       
    var errorStatus = Windows.Networking.Sockets.WebSocketError.getStatus(reason.number);
    if (errorStatus === Windows.Web.WebErrorStatus.cannotConnect || 
        errorStatus === Windows.Web.WebErrorStatus.notFound || 
        errorStatus === Windows.Web.WebErrorStatus.requestTimeout) {
        WinJS.log && WinJS.log("Cannot connect to the server");
    }
    else {
        WinJS.log && WinJS.log("Failed to connect: " + errorStatus);
    }
}

For parameter validation errors, an app can also use the HRESULT from the exception to learn more detailed information on the error that caused the exception. In apps using JavaScript, the Error object represents an error during app execution when an exception occurs. The Error.number property returns the HRESULT assigned to the specific exception. Possible HRESULT values are listed in the Winerror.h header file. For most parameter validation errors, the HRESULT returned is E_INVALIDARG.

Exceptions in Windows.Networking.BackgroundTransfer

The Windows.Networking.backgroundTransfer namespace has convenient helper methods and uses enumerations in the Windows.Networking.Sockets namespace for handling errors. This can be useful for handling specific network exceptions differently in your app.

An error encountered on an asynchronous method in the Windows.Networking.backgroundTransfer namespace is returned as an HRESULT value. The BackgroundTransferError.GetStatus method is used to convert a network error from a background transfer operation to a WebErrorStatus enumeration value. Most of the WebErrorStatus enumeration values correspond to an error returned by the native HTTP or FTP client operation. An app can filter on specific WebErrorStatus enumeration values to modify app behavior depending on the cause of the exception.

For parameter validation errors, an app can also use the HRESULT from the exception to learn more detailed information on the error that caused the exception. In apps using JavaScript, the Error object represents an error during app execution when an exception occurs. The Error.number property returns the HRESULT assigned to the specific exception. Possible HRESULT values are listed in the Winerror.h header file. For most parameter validation errors, the HRESULT returned is E_INVALIDARG.

Exceptions in Windows.Web.Http

The Windows.Web.Http namespace lacks a convenience function. So an app using HttpClient and other classes in this namespace needs to use the HRESULT value.

In apps using JavaScript, the Error object represents an error during app execution when an exception occurs. The Error.number property returns the HRESULT assigned to the specific exception. The Error.description property returns the message that describes the exception. However some exceptions may lack a value for the Error.description property. Most of the possible HRESULT values are listed in the Winerror.h header file. An app can filter on specific HRESULT values to modify app behavior depending on the cause of the exception.

For most parameter validation errors, the HRESULT returned is E_INVALIDARG. For some illegal method calls, the HRESULT returned is E_ILLEGAL_METHOD_CALL.

The following sample code shows how to filter on an exception using the HRESULT.

var uri = new Uri("http://example.com/datalist.aspx");
var httpClient = new HttpClient();

// Always catch network exceptions for async methods
httpClient.GetStringAsync(uri).done(function () {
        // get completed
    }, onError);


function onError(reason) {
    // Details in error.message and error.number       
    var errorStatus = reason.number;
    if (errorStatus === INET_E_RESOURCE_NOT_FOUND || 
        errorStatus === INET_E_CANNOT_CONNECT ) {
        WinJS.log && WinJS.log("Cannot connect to the server");
    }
    else {
        WinJS.log && WinJS.log("Failed to connect: " + errorStatus);
    }
}

Other resources

Adding support for networking

How to set background connectivity options

Transferring data in the background

Troubleshooting and debugging network connections

Reference

HttpClient

MessageWebSocket

StreamSocket

StreamWebSocket

Windows.Networking.BackgroundTransfer

Windows.Networking.Sockets

Windows.Web.Http