On September 25th, 2024, we released v2 of the Apps SDK. To learn what’s new and how to upgrade, see Migration FAQ and Migration guide.

Handling errors

How to handle errors thrown by the Apps SDK.

In the Apps SDK, all methods have the potential to throw an error if something goes wrong, such as a request timing out or the user being disconnected from the internet.

While developing an app, it's important to:

  • Be mindful of errors that may occur.
  • Handle errors as gracefully as possible.

Our design guidelines help you create a high-quality app that easily passes app review.

How to handle errors

  1. Import CanvaError from the @canva/error package:

    import { CanvaError } from "@canva/error";
    TS
  2. When calling a method from the Apps SDK, wrap it in a try/catch block:

    import { addElementAtPoint } from "@canva/design";
    import { CanvaError } from "@canva/error";
    try {
    await addElementAtPoint({
    type: "embed",
    url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    });
    } catch (error) {
    console.log(error);
    }
    TS
  3. In the catch block, check if the error is an instance of a CanvaError:

    if (error instanceof CanvaError) {
    console.log("CanvaError:", error.code);
    }
    TS

    The CanvaError object contains two properties:

    • code - A string that identifies the reason for the error.
    • message - Additional information about the error.
  4. Use the code property to handle the possible error cases:

    if (error instanceof CanvaError) {
    switch (error.code) {
    case "permission_denied":
    console.log("You don't have the required permissions.");
    break;
    case "user_offline":
    console.log("You're offline.");
    break;
    case "timeout":
    console.log("The request timed out.");
    break;
    }
    }
    TS

You don't have to handle all error codes for all methods — most methods only have the potential to throw a subset of the available errors.

Using the Promise syntax

The try/catch syntax is the modern way to catch errors, and it's the approach that's used throughout the documentation, but it's not a strict requirement. You can also use the Promise syntax:

import { addElementAtPoint } from "@canva/design";
import { CanvaError } from "@canva/error";
addElementAtPoint({
type: "embed",
url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
}).catch((error) => {
if (error instanceof CanvaError) {
console.log("CanvaError:", error.code);
}
console.log(error);
});
TS

Handling other errors

Be mindful of the fact that other errors may occur throughout the lifecycle of an app, such as errors from native browser APIs or third-party libraries — that is, handling errors from the Apps SDK doesn't mean that all possible errors are handled.

List of error codes

When a method in the Apps SDK throws an error, there's a limited range of possible error codes. This section lists all of the possible error codes that may appear in a CanvaError object.

bad_external_service_response

A response from an external service is invalid or malformed.

Example: When redirecting back to Canva at the end of an authentication flow, the URL is malformed.

bad_request

The app has made a request that’s invalid or malformed.

Example: The app calls a function without a required parameter.

failed_precondition

The app hasn’t met a precondition.

internal_error

There’s an error in the App SDK’s internal implementation.

Example: There's an underlying issue in Canva's backend.

not_allowed

The app is not allowed to perform the specified operation.

Example: The app tries to call the navigator.clipboard.write method, which has been disabled due to it not being cross-browser compatible.

not_found

The app can’t retrieve the specified resource.

Example: The app tries to operate on an asset reference that doesn't exist.

quota_exceeded

The app or user has exceeded their allocated quota for a resource or service.

Example: The app can't upload a file because the user is out of storage space.

permission_denied

The app doesn’t have sufficient permissions.

Example: The app tries to create an element without having sufficient permissions.

rate_limited

The app has made too many requests within a certain time period. The reference page for each API method includes a description of any rate limits. For example, the rate limit for requestExport.

Example: The app tries to create too many elements in a short period of time.

timeout

The operation exceeded the maximum allowed time to complete.

unsupported_surface

An API is called from an incompatible surface. A surface may be incompatible with an API for technical reasons or to avoid a confusing user experience.

Example: An app tries to open a font picker from an image overlay.

user_offline

The user is offline.

Example: The user tries to authenticate without being connected to the internet.