---
id: flow--try-catch
title: "Try catch"
summary: "Error handler: runs the components behind `Try`; if they fail with an error, the record is sent to `Catch` with the error details in the metadata property `Error`."
audience: user
keywords: "input, try, catch, rethrowerror, logerror"
---
# Try catch

Error handler: runs the components behind `Try`; if they fail with an error, the record is sent to `Catch` with the error details in the metadata property `Error`.

## Pins

| Pin | Kind | Types | Description |
|---|---|---|---|
| Input | start | any | Record to process. If left unconnected, the system calls it once at flow start (with `Viaducta.TypeSystem.Metadata.NoInputData`). |
| Try | output | same as input | The protected branch. |
| Catch | error output | same as input | Called with the original input record when the `Try` branch failed. |

## Configuration

| Field | Type | Default | Description |
|---|---|---|---|
| `RethrowError` | boolean | `false` | `true`: after `Catch` has run, the same error is thrown again to the caller (an outer Try catch, Retry, HTTP listener, ...). |
| `LogError` | boolean | `true` | `true`: every handled error is written to the flow log ("The try catch plugin handled exception ..."). |

## Behaviour

- Before calling `Try`, the metadata property `Error` (`Viaducta.Plugins.TryCatch.TryCatchPluginMetadata`) is reset (`Exception` = null, `FlowId` / `FlowName` = current flow) and the component registers itself as error handler on the metadata.
- If an exception comes back from the `Try` branch (synchronously, e.g. from an Error component, a failing Http client or script), the component:
  1. unwraps a single inner exception of an `AggregateException`;
  2. logs it if `LogError` is `true`;
  3. sets `Error`: `Exception` (the exception, `Message` etc.), `ComponentId`, `ComponentName`, `FlowId`, `FlowName` (component and flow where it occurred, when known);
  4. calls `Catch` with the original input record and the metadata;
  5. rethrows the original error if `RethrowError` is `true`, otherwise the request continues as handled (the caller sees success).
- Components that report errors asynchronously (on their own threads) call the error handler registered on the metadata; then `Catch` is called the same way.
- An exception thrown inside the `Catch` branch is passed back to the caller.

## Notes

- `UnRecoverableFlowException` (failed expression evaluation, no matching connection for a type, explicit unrecoverable errors) is not caught: the system logs it, pauses and stops the flow.
- When the flow runs in debug mode, component errors are reported to the debugger and are not passed back to the Try catch, so `Catch` is not called.
- Errors handled downstream (e.g. by an inner Try catch or a component's own error pin) do not reach this component.
- `RethrowError` always rethrows, even if `Error` was changed or reset in the `Catch` branch.
- Nested Try catch components share the one `Error` metadata property; an inner Try catch overwrites it. For asynchronous errors the first Try catch registered on the request (the outermost) handles the error.
- The `Error` metadata stays on the request after `Catch`; check `Error.Exception` for null to see whether an error occurred.

## Example

```json
{ "RethrowError": false, "LogError": true }
```

Http listener → **Try catch** → (`Try`) Http client → Http response ; (`Catch`) → Http response (status 500, `Error.Exception.Message`)
