Handle Errors {#uc_appendix_handle_errors}
==========================================

The `Unified Checkout` SDK uses a structured error object for all error scenarios. Errors are returned as exceptions from asynchronous methods and are also returned as events for centralized handling.

UnifiedCheckoutError {#uc_handle_errors_uc_checkout}
====================================================

All SDK errors are instances of `UnifiedCheckoutError` with these properties:

|     Property      |    Type    |                                     Description                                      |
|-------------------|------------|--------------------------------------------------------------------------------------|
| `correlationId`   | `string?`  | The correlation ID from an underlying API call, when applicable.                     |
| `details`         | `unknown?` | Additional error-specific information. This is often an array of objects.            |
| `informationLink` | `string?`  | The URL linked to the online documentation for this error.                           |
| `message`         | `string`   | This property is a human-readable description of the error.                          |
| `name`            | `string`   | The value is always `"UnifiedCheckoutError"`.                                        |
| `reason`          | `string`   | This property is a machine-readable error code, such as `"CAPTURE_CONTEXT_INVALID"`. |
[`UnifiedCheckoutError` Properties]

Detect Errors {#uc_handle_errors_detect}
========================================

Errors may be serialized through `postMessage`. `Visa Acceptance Solutions` recommends that you use the `name` property instead of `instanceof`:

```
try {
  const result = await checkout.mount('#buttons');
} catch (error) {
  if (error.name === 'UnifiedCheckoutError') {
    // Access error.reason, error.message, error.details
  }
}
```

You can also write a helper function that can be reused:

```
function isUnifiedCheckoutError(obj) {
  return (
    obj !== null &&
    typeof obj === 'object' &&
    obj.name === 'UnifiedCheckoutError' &&
    typeof obj.reason === 'string' &&
    typeof obj.message === 'string'
  );
}
```

Error Handling Patterns {#uc_handle_errors_pattern}
===================================================

Try/Catch
---------

```
try {
  const client = await VAS.UnifiedCheckout(sessionJWT);
  const checkout = await client.createCheckout();
  const result = await checkout.mount('#buttons');
} catch (error) {
  console.error(error.reason, error.message);
}
```

Promise .catch()
----------------

```
VAS.UnifiedCheckout(sessionJWT)
  .then(client =&gt; client.createCheckout())
  .then(checkout =&gt; checkout.mount('#buttons'))
  .catch(error =&gt; console.error(error.reason, error.message));
```

Centralized Error Logging via Events
------------------------------------

Errors from all integrations are applicable up to the client level. Use `client.on('error')` for centralized logging:

```
const client = await VAS.UnifiedCheckout(sessionJWT);

client.on('error', (err) =&gt; {
  errorReporter.send({
    source: err.source,   // "checkout", "trigger", "button", or "client"
    code: err.code,
    message: err.message
  });
});
```

`Visa Acceptance Solutions` recommends that you do this as it catches errors from all checkouts, triggers, and buttons created from this client instance.

Error Codes {#uc_handle_errors_codes}
=====================================

Initialization Errors
---------------------

These errors are returned during `VAS.UnifiedCheckout(sessionJWT)`:

|          Reason           |                                                          Description                                                           |
|---------------------------|--------------------------------------------------------------------------------------------------------------------------------|
| `CAPTURE_CONTEXT_EXPIRED` | The supplied JWT has expired. Generate a new session.                                                                          |
| `CAPTURE_CONTEXT_INVALID` | The session JWT is not valid. For example, it has a bad signature or is malformed.                                             |
| `UNUSED_TARGET_ORIGINS`   | One or more `targetOrigins` in the session do not match the current page origin. The `details` array lists the unused origins. |
[Initialization Reason Values]

Mount Errors
------------

These errors are returned during `checkout.mount()` or `trigger.mount()`:

|           Reason            |                                                                 Description                                                                  |
|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------|
| `CHECKOUT_ALREADY_MOUNTED`  | The checkout or trigger is already mounted. Call `unmount()` first, or create a new instance.                                                |
| `MOUNT_CONTAINER_SELECTOR`  | The CSS selector does not match any Document Object Model (DOM) element. Check that the container exists before calling `mount()`.           |
| `MOUNT_ERROR`               | A problem occurred loading the payment iframe.                                                                                               |
| `MOUNT_INVALID_CONTAINER`   | The supplied container parameter is not a valid CSS selector string or `HTMLElement`.                                                        |
| `MOUNT_PAYMENT_TIMEOUT`     | A payment method timed out during initialization.                                                                                            |
| `MOUNT_PAYMENT_UNAVAILABLE` | No payment types could be presented to the customer. This may be due to browser or device support, or errors during checkout initialization. |
| `MOUNT_SIDEBAR_OPTIONS`     | The supplied container parameter is invalid for sidebar mode.                                                                                |
| `MOUNT_TOKEN_TIMEOUT`       | Token creation timed out during mount. This may indicate a network issue.                                                                    |
| `MOUNT_TOKEN_XHR_ERROR`     | A network error occurred during token creation. Check the customer's connectivity.                                                           |
[Mount Reason Values]

Complete Errors
---------------

These errors are returned during `checkout.complete()` or `trigger.complete()`:

|               Reason               |                                            Description                                             |
|------------------------------------|----------------------------------------------------------------------------------------------------|
| `COMPLETE_AUTHENTICATION_CANCELED` | The customer cancelled the `3-D Secure` authentication step-up.                                    |
| `COMPLETE_AUTHENTICATION_FAILED`   | The `3-D Secure` authentication step-up failed.                                                    |
| `COMPLETE_ERROR`                   | A general error occurred during transaction completion.                                            |
| `COMPLETE_IN_PROGRESS`             | complete() has already been called and has not yet finished. Wait for the current call to resolve. |
| `COMPLETE_NOT_ALLOWED`             | Complete is not allowed for this transaction, such as when `autoProcessing` is set to `true`.      |
| `COMPLETE_TRANSACTION_CANCELLED`   | The customer cancelled the transaction.                                                            |
| `COMPLETE_TRANSACTION_FAILED`      | The transaction failed during processing.                                                          |
| `COMPLETE_VALIDATION_ERROR`        | The parameters supplied to complete() have a validation error. Check the `details` for specifics   |
[Complete Reason Values]

Checkout Errors
---------------

|            Reason             |                       Description                        |
|-------------------------------|----------------------------------------------------------|
| `CHECKOUT_ERROR`              | A general checkout error occurred.                       |
| `CHECKOUT_PAYMENT_PARAMETERS` | One or more payment parameters have a validation error.  |
| `CHECKOUT_VALIDATION_PARAMS`  | One or more checkout parameters have a validation error. |
[Checkout Reason Values]

Trigger Errors
--------------

|                Reason                |                                                   Description                                                    |
|--------------------------------------|------------------------------------------------------------------------------------------------------------------|
| `TRIGGER_PAYMENT_TYPE_NOT_SUPPORTED` | The specified payment type cannot be used with a trigger. Only `PANENTRY` and `CLICKTOPAY` values are supported. |
[Trigger Reason Values]

**Payment-Specific Errors**
---------------------------

|                 Reason                 |                      Description                      |
|----------------------------------------|-------------------------------------------------------|
| `CLICK_TO_PAY_SDK_LOAD_ERROR`          | The `Click to Pay`SDK failed to load.                 |
| `ENCRYPT_CARD_FOR_SRC_ENROLMENT_ERROR` | Card encryption for `Click to Pay` enrollment failed. |
| `GOOGLEPAY_CHECKOUT_ERROR`             | A Google Pay checkout error occurred.                 |
| `LAUNCH_SRC_CHECKOUT_ERROR`            | Launching the `Click to Pay` checkout failed.         |
| `TRIGGER_PAYMENT_TYPE_NOT_SUPPORTED`   | The payment type is not supported for triggers.       |
[Payment-Specific Reason Values]

General Errors
--------------

|   Reason Code   |          Description           |
|-----------------|--------------------------------|
| `UNKNOWN_ERROR` | An unknown error has occurred. |

