# Error Handling on the Client

\[ **This document was written for WCF Services Version 1 Service Pack 2 and might not be up to date** \
&#x20;Please see [Release Notes](https://github.com/OpenRIAServices/OpenRiaServices/releases) or [Changelog](https://github.com/OpenRIAServices/OpenRiaServices/blob/main/Changelog.md) for a list of changes since WCF RIA Services ]

This topic describes how you typically want to handle errors and take certain steps in response to the errors that you retrieve or modify data from a client. With Open Ria Services, you handle errors by providing a callback method for data operations and checking for errors in that callback method. Using callback methods is necessary because calls to data operations are asynchronous and therefore any exceptions are thrown asynchronously. By default, an exception is thrown for any errors in domain operations. Open Ria Services provides ways for you to handle the errors and specify that the framework not throw an exception.

## Error Handling When Loading Data

When loading data from a query method, you can either handle the error or choose to ignore the error. Specifically, you choose from the following options:

* Use a Load method that has a parameter for a callback method. In the callback method, handle the error and call the [MarkErrorAsHandled](https://github.com/OpenRIAServices/OpenRiaServices/tree/086ea8c8fcb115000749be6b2b01cd43bb95bf80/docs/ff422800.md) method to indicate that the exception is not thrown.
* Use a Load method that has a boolean parameter named throwOnError. Set throwOnError to false when you call the Load method to indicate that you do not want an exception thrown for query errors.
* Use the [Load](https://github.com/OpenRIAServices/OpenRiaServices/tree/086ea8c8fcb115000749be6b2b01cd43bb95bf80/docs/ff423329.md) method which does not have a parameter for a callback method or a boolean parameter. Any errors when running the query will result in an unhandled exception.

The following example shows how to load data from a query and specify a callback method that checks for errors from the load operation.

```
Private _customerContext As New CustomerDomainContext

Public Sub New()
    InitializeComponent()

    Dim loadOp = Me._customerContext.Load(Me._customerContext.GetCustomersQuery(), AddressOf OnLoadCompleted, Nothing)
    CustomerGrid.ItemsSource = loadOp.Entities
End Sub

Private Sub OnLoadCompleted(ByVal lo As LoadOperation(Of Customer))
    If (lo.HasError) Then
        MessageBox.Show(String.Format("Retrieving data failed: {0}", lo.Error.Message))
        lo.MarkErrorAsHandled()
    End If
End Sub
```

```csharp
private CustomerDomainContext _customerContext = new CustomerDomainContext();

public MainPage()
{
    InitializeComponent();

    LoadOperation<Customer> loadOp = this._customerContext.Load(this._customerContext.GetCustomersQuery(), OnLoadCompleted, null);
    CustomerGrid.ItemsSource = loadOp.Entities;
}

private void OnLoadCompleted(LoadOperation<Customer> lo)
{
    if (lo.HasError)
    {
        MessageBox.Show(string.Format("Retrieving data failed: {0}", lo.Error.Message));
        lo.MarkErrorAsHandled();
    }
}
```

## Error Handling When Submitting Data

When submitting data, you cannot choose to turn off the exceptions as you can with the Load method. Any errors when submitting data will result in an exception. Specifically, you choose from the following options:

* Use the [SubmitChanges](https://github.com/OpenRIAServices/OpenRiaServices/tree/086ea8c8fcb115000749be6b2b01cd43bb95bf80/docs/ff422910.md) method and provide a callback method as a parameter. In the callback method, handle the error and call the [MarkErrorAsHandled](https://github.com/OpenRIAServices/OpenRiaServices/tree/086ea8c8fcb115000749be6b2b01cd43bb95bf80/docs/ff422800.md) method to indicate that the exception is not thrown.
* Use the [SubmitChanges](https://github.com/OpenRIAServices/OpenRiaServices/tree/086ea8c8fcb115000749be6b2b01cd43bb95bf80/docs/ff422910.md) method. Any errors when submitting the data will result in an unhandled exception.

The following example shows how to call the [SubmitChanges](https://github.com/OpenRIAServices/OpenRiaServices/tree/086ea8c8fcb115000749be6b2b01cd43bb95bf80/docs/ff422910.md) method with a callback method for handling errors.

```
Private Sub SaveButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    _customerContext.SubmitChanges(AddressOf OnSubmitCompleted, Nothing)
End Sub

Private Sub RejectButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    _customerContext.RejectChanges()
    CheckChanges()
End Sub

Private Sub CustomerGrid_RowEditEnded(ByVal sender As System.Object, ByVal e As System.Windows.Controls.DataGridRowEditEndedEventArgs)
    CheckChanges()
End Sub

Private Sub CheckChanges()
    Dim changeSet = _customerContext.EntityContainer.GetChanges()
    ChangeText.Text = changeSet.ToString()

    Dim hasChanges = _customerContext.HasChanges
    SaveButton.IsEnabled = hasChanges
    RejectButton.IsEnabled = hasChanges
End Sub

Private Sub OnSubmitCompleted(ByVal so As SubmitOperation)
    If (so.HasError) Then
        MessageBox.Show(String.Format("Submit Failed: {0}", so.Error.Message))
        so.MarkErrorAsHandled()
    End If
    CheckChanges()
End Sub
```

```csharp
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
    _customerContext.SubmitChanges(OnSubmitCompleted, null);
}

private void RejectButton_Click(object sender, RoutedEventArgs e)
{
    _customerContext.RejectChanges();
    CheckChanges();
}

private void CustomerGrid_RowEditEnded(object sender, DataGridRowEditEndedEventArgs e)
{
    CheckChanges();
}

private void CheckChanges()
{
    EntityChangeSet changeSet = _customerContext.EntityContainer.GetChanges();
    ChangeText.Text = changeSet.ToString();

    bool hasChanges = _customerContext.HasChanges;
    SaveButton.IsEnabled = hasChanges;
    RejectButton.IsEnabled = hasChanges;
}

private void OnSubmitCompleted(SubmitOperation so)
{
    if (so.HasError)
    {
        MessageBox.Show(string.Format("Submit Failed: {0}", so.Error.Message));
        so.MarkErrorAsHandled();
    }
    CheckChanges();
}
```

## Error Handling With Invoke Operations

When invoking an operation, you have the same options available as when you submit data. Specifically, you choose from the following options:

* Include a callback method when you call the invoke operation. In the callback method, handle the error and call the [MarkErrorAsHandled](https://github.com/OpenRIAServices/OpenRiaServices/tree/086ea8c8fcb115000749be6b2b01cd43bb95bf80/docs/ff422800.md) method to indicate that the exception is not thrown.
* Call the invoke operation without including a callback method. Any errors when invoking the method will result in an unhandled exception.

The following example shows an invoke operation with a callback method.

```
Dim invokeOp As InvokeOperation(Of Integer)
invokeOp = customerContext.GetLocalTemperature(selectedPostalCode, AddressOf OnInvokeCompleted, Nothing)

Private Sub OnInvokeCompleted(ByVal invOp As InvokeOperation(Of Integer))
  If (invOp.HasError) Then
    MessageBox.Show(String.Format("Method Failed: {0}", invOp.Error.Message))
    invOp.MarkErrorAsHandled()
  Else
    result = invOp.Value
  End If
End Sub
```

```csharp
InvokeOperation<int> invokeOp = customerContext.GetLocalTemperature(selectedPostalCode, OnInvokeCompleted, null);

private void OnInvokeCompleted(InvokeOperation<int> invOp)
{
  if (invOp.HasError)
  {
    MessageBox.Show(string.Format("Method Failed: {0}", invOp.Error.Message));
    invOp.MarkErrorAsHandled();
  }
  else
  {
    result = invokeOp.Value;
  }
}
```

## Error Handling with Authentication Service

The [AuthenticationService](https://github.com/OpenRIAServices/OpenRiaServices/tree/086ea8c8fcb115000749be6b2b01cd43bb95bf80/docs/ff457927.md) class enables you to provide a callback method when you call the following methods:

* [LoadUser](https://github.com/OpenRIAServices/OpenRiaServices/tree/086ea8c8fcb115000749be6b2b01cd43bb95bf80/docs/ff457880.md)
* [Login](https://github.com/OpenRIAServices/OpenRiaServices/tree/086ea8c8fcb115000749be6b2b01cd43bb95bf80/docs/ff457850.md)
* [Logout](https://github.com/OpenRIAServices/OpenRiaServices/tree/086ea8c8fcb115000749be6b2b01cd43bb95bf80/docs/ff457902.md)
* [SaveUser](https://github.com/OpenRIAServices/OpenRiaServices/tree/086ea8c8fcb115000749be6b2b01cd43bb95bf80/docs/ff457896.md)

In the callback method, you can provide code to handle errors from the authentication service. The following example shows how to call the Login method from an event handler for a login button. A callback method is included to respond to the results of the login operation.

```
Private Sub LoginButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim lp As LoginParameters = New LoginParameters(UserName.Text, Password.Password)
    WebContext.Current.Authentication.Login(lp, AddressOf Me.LoginOperation_Completed, Nothing)
    LoginButton.IsEnabled = False
    LoginResult.Text = ""
End Sub

Private Sub LoginOperation_Completed(ByVal lo As LoginOperation)
    If (lo.HasError) Then
        LoginResult.Text = lo.Error.Message
        LoginResult.Visibility = System.Windows.Visibility.Visible
        lo.MarkErrorAsHandled()
    ElseIf (lo.LoginSuccess = False) Then
        LoginResult.Text = "Login failed. Please check user name and password."
        LoginResult.Visibility = System.Windows.Visibility.Visible
    ElseIf (lo.LoginSuccess = True) Then
        SetControlVisibility(True)
    End If
    LoginButton.IsEnabled = True
End Sub
```

```csharp
private void LoginButton_Click(object sender, RoutedEventArgs e)
{
    LoginParameters lp = new LoginParameters(UserName.Text, Password.Password);
    WebContext.Current.Authentication.Login(lp, this.LoginOperation_Completed, null);
    LoginButton.IsEnabled = false;
    LoginResult.Text = "";
}

private void LoginOperation_Completed(LoginOperation lo)
{
    if (lo.HasError)
    {
        LoginResult.Text = lo.Error.Message;
        LoginResult.Visibility = System.Windows.Visibility.Visible;
        lo.MarkErrorAsHandled();
    }
    else if (lo.LoginSuccess == false)
    {
        LoginResult.Text = "Login failed. Please check user name and password.";
        LoginResult.Visibility = System.Windows.Visibility.Visible;
    }
    else if (lo.LoginSuccess == true)
    {
        SetControlVisibility(true);
    }
    LoginButton.IsEnabled = true;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://openriaservices.gitbook.io/openriaservices/ee707349/ee807307.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
