# Exceptions and Error Handling

> Catch FilterException and LicenseLevelException in WPF code-behind, check return values, handle Task.Run errors and use DispatcherUnhandledException.

- **Product:** TX Text Control .NET for WPF
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for WPF > Document Processing > Exceptions and Error Handling
- **3209 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-processing/exceptions/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-processing/exceptions/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-processing/exceptions/llms-full.txt

---

Which calls of TX Text Control can fail, and how does a WPF application find out? Errors of the document engine, such as a file that can't be converted or a feature outside the licensed edition, arrive as exceptions of TX Text Control. Wrong arguments cause the usual .NET exceptions, and many expected failures come back as a return value instead. Each needs its own handling in the code-behind: a `try` block, a check of the result, or a handler of last resort for the whole application.

The examples belong in *MainWindow.xaml.cs* with the `TextControl` named `textControl1`. Specific error messages and their fixes are collected in [Troubleshooting](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/troubleshooting/llms-full.txt).

*MainWindow.xaml.cs* needs these `using` directives:

```csharp
using System;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.Win32;
using TXTextControl;
```

### How TX Text Control Reports Errors

| Kind of error | How it's reported | Examples |
|---|---|---|
| An error of the document engine | An exception class of TX Text Control | A document that can't be loaded |
| Wrong use of the programming interface | `ArgumentException`, `ArgumentNullException` or `ArgumentOutOfRangeException` for a wrong parameter or property value; `InvalidOperationException` for a call that the object's state doesn't allow | A conditional instruction without a name |
| An expected failure | A return value | An `Add` method returns `false` or an `AddResult`; [ServerTextControl.Create](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/servertextcontrol/create-method/llms-full.txt) returns `false` |

Return values throw nothing, so check them where your code depends on the result.

### TX Text Control Exceptions

- **[FilterException](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/filterexception/llms-full.txt)**: a document can't be converted to or from a format while it is loaded or saved.
- **[LicenseLevelException](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/licenselevelexception/llms-full.txt)**: the licensed edition doesn't contain the feature your code uses.
- **[TextEditorException](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/texteditorexception/llms-full.txt)**: an error occurs while text is edited.
- **[FormulaException](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/formulaexception/llms-full.txt)** and **[NumberFormatException](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/numberformatexception/llms-full.txt)**: a table formula or the number format of its result has invalid syntax. [FormulaException.CharacterIndex](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/formulaexception/characterindex-property/llms-full.txt) and [NumberFormatException.CharacterIndex](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/numberformatexception/characterindex-property/llms-full.txt) point at the first invalid character, counting from 1.
- **[DocumentServer.MergeCanceledException](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-documentserver/mergecanceledexception/llms-full.txt)**: a merge was canceled with [DataRowMergedEventArgs.Cancel](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-documentserver/mailmerge-datarowmergedeventargs/cancel-property/llms-full.txt).
- **[DocumentServer.Json.ParserException](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-documentserver-json/parserexception/llms-full.txt)** and the classes derived from it: [MailMerge.MergeJsonData](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-documentserver/mailmerge/mergejsondata-method/llms-full.txt) received invalid JSON.

Each message contains an error number in parentheses, for example `(1-1D01)`. It is more exact than the text of the message; the blog article [Text Control Error Navigator Launched](https://www.textcontrol.com/blog/2022/08/15/text-control-error-navigator-launched/) explains how to look it up.

### Catch Errors When Opening a Document

Documents come from outside your application, so loading needs a `try` block. [FilterException.Reason](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/filterexception/reason-property/llms-full.txt) is a [FilterException.FilterError](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/filterexception/filtererror-enumeration/llms-full.txt) value that names the cause:

```csharp
private void Open_Click(object sender, RoutedEventArgs e)
{
    OpenFileDialog dialog = new OpenFileDialog { Filter = "Word documents|*.docx" };

    if (dialog.ShowDialog(this) != true)
    {
        return;
    }

    try
    {
        textControl1.Load(dialog.FileName, StreamType.WordprocessingML);
    }
    catch (FilterException exception)
    {
        string text = exception.Reason switch
        {
            FilterException.FilterError.WrongFileType => "The file isn't a Word document.",
            FilterException.FilterError.Encrypted => "The document is encrypted.",
            FilterException.FilterError.CannotOpen => "The file couldn't be opened.",
            _ => "The document couldn't be loaded."
        };

        MessageBox.Show(this, $"{text}\n\n{exception.Message}", "Open", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}
```

The code works as follows:

- `OpenFileDialog` of `Microsoft.Win32` is the file dialog of WPF; its `ShowDialog` returns a nullable `bool`.
- [WPF.TextControl.Load](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/load-method/llms-full.txt) throws the `FilterException` when the document can't be converted.
- The `switch` expression gives three common reasons a message of their own. Others are `CannotRead`, `FileTooBig`, `Unsupported`, `NotWellFormed` and `InvalidPassword`, and saving can fail with `NonEmbeddableFont`, for example.
- Errors of the file system, such as an `IOException` for a locked file, aren't a `FilterException`; catch them separately if needed.

Every reason and its fix is listed in [Document Conversion](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/troubleshooting/conversion/llms-full.txt) in Troubleshooting.

### Handle a Feature of Another Edition

A `LicenseLevelException` points to code that uses a feature the licensed edition doesn't have, such as form fields in the Professional edition. Change the code or the license: [Editions](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/overview/editions/llms-full.txt) lists the features per edition, and [Licensing](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/troubleshooting/licensing/#a-feature-isn-t-available-in-your-edition) in Troubleshooting shows the messages. Where the application can go on without the feature, catch the exception:

```csharp
private void InsertFormField_Click(object sender, RoutedEventArgs e)
{
    try
    {
        textControl1.FormFields.Add(new TextFormField(1440));
    }
    catch (LicenseLevelException exception)
    {
        MessageBox.Show(this, exception.Message, "Not available", MessageBoxButton.OK, MessageBoxImage.Information);
    }
}
```

### Catch Errors of Background Work

Code in `Task.Run` runs on another thread, and an exception there is stored in the task. `await` throws it again on the UI thread, so a `try` block around the `await` catches it:

```csharp
private async void Convert_Click(object sender, RoutedEventArgs e)
{
    try
    {
        await Task.Run(() =>
        {
            using (ServerTextControl tx = new ServerTextControl())
            {
                if (!tx.Create())
                {
                    throw new InvalidOperationException("TX Text Control could not be initialized.");
                }

                tx.Load("contract.docx", StreamType.WordprocessingML);
                tx.Save("contract.pdf", StreamType.AdobePDF);
            }
        });

        MessageBox.Show(this, "contract.pdf created.");
    }
    catch (FilterException exception)
    {
        MessageBox.Show(this, $"{exception.Reason}: {exception.Message}", "Conversion failed");
    }
}
```

The `using` block disposes the `ServerTextControl` even when an exception leaves it. [Using ServerTextControl in Desktop Applications](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-processing/servertextcontrol/llms-full.txt) covers background work. A `MergeCanceledException` from a merge you cancel in a `DataRowMerged` handler is caught the same way around the call that merges; [Merge Events](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/mail-merge/events/llms-full.txt) describes the event.

### Handle Exceptions Nobody Caught

An exception that reaches the WPF dispatcher without a `catch` block ends the application. The TX Words samples handle the `DispatcherUnhandledException` event of the application, show the message and mark the exception as handled, so that the user can continue after a `LicenseLevelException`. Attach the handler in *App.xaml.cs*:

```csharp
using System.Windows;
using System.Windows.Threading;

public partial class App : Application
{
    public App()
    {
        DispatcherUnhandledException += App_DispatcherUnhandledException;
    }

    private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
    {
        MessageBox.Show(e.Exception.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);

        // Continue only after exceptions the application can recover from
        e.Handled = e.Exception is TXTextControl.LicenseLevelException;
    }
}
```

`e.Handled = true` keeps the application running. Set it only for exceptions after which your application is in a usable state, and catch other errors where you call TX Text Control. [Dispatcher and Thread Access](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/troubleshooting/dispatcher/#an-exception-ends-the-application) in Troubleshooting describes the case.

### Next Steps

- [Troubleshooting](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/troubleshooting/llms-full.txt): error messages and their fixes.
- [Document Conversion](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/troubleshooting/conversion/llms-full.txt): every `FilterException` reason.
- [Loading Documents](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-processing/loading/llms-full.txt): load settings for protected and special documents.
- [Handling Untrusted Documents](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/security/untrusted-documents/llms-full.txt): documents from unknown sources.

---

## Nearby

- **Previous:** [Using ServerTextControl in Desktop Applications](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-processing/servertextcontrol/llms-full.txt)
- **Next:** [Conditional Instructions](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-processing/conditional-instructions/llms-full.txt)
