Handle common error causes
Leverage the Defer Console filters to narrow down error causes.
Sh#! happens. Errors occur. The network slows down, memory runs out, an external resource becomes unavailable. Maybe there’s a security issue.
Whatever the case may be, an API must be able to clearly identify the error, catch it, and give you the tools to manage the error—ideally, programmatically and in real-time.
In this guide, you’ll learn how to use Defer to manage the following kinds of errors:
- Timeouts
- External failures
- Runtime errors
- Internal errors
Filter executions for a given Error Reason
You can always go to the Defer Console to quickly identify errors that impact your application. The Defer Console’s Error Reason filter allows you to analyze errors by error type:
First, select the metadata filter and Error reason
Finally, select Error reason
You can now inspect executions for the select Error reason
How to handle timeouts
Unwanted timeouts due to external factors, such as network or 3rd party API outages, can compromise your concurrency capabilities. Here are two patterns that mitigate timeouts:
1 - Timeout control with the maxDuration
option
Since
@defer/client@1.6.0
,
you can specify a maxDuration
to avoid unwanted timeouts.
const importContacts = (companyId: string, contacts: Contact[]) => {
// ...
};
export default defer(importContacts, {
maxDuration: 10, // will timeout after 10secs
});
2 - Canceling executions
Since
@defer/client@1.8.0
,
you can also cancel pending executions from the API.
import { cancelExecution } from "@defer/client";
// ...
const { id } = await cancelExecution(executionId);
// ...
Note: You can also cancel pending and running executions from the Defer Console.
How to handle runtime and external errors
External errors are linked to 3rd party API outages or network issues, while
runtime errors range from typos and malformed data to memory issues. Both can
be mitigated with the retry
option and by enabling Slack notifications.
Here’s an overview of Defer’s retry capabilities. For a full discussion with use case and notification examples, please read our Deep Dive into Defer’s Retry Strategies.
Standard Retry strategies
Defer defaults to no retry:
import { defer } from "@defer/client";
async function myBgFunction() {
/* ... */
}
export default defer(myBgFunction);
// is equivalent to:
export default defer(myBgFunction, { retry: false });
Adding { retry: true }
to your background function will enable the retry
option, which defaults up to 13 retries.
You can also control the amount of retries by replacing true
with a number,
such as { retry: 5 }
.
export default defer(myBgFunction, { retry: 5 });
The retry
combined with concurrency
is a simple way to deal with API
rate-limiting.
For example, the below function—running for 500ms—will ensure that the 3rd party API will be called only once per second:
export default defer(myBgFunction, {
retry: 5,
concurrency: 2,
});
The { retry: false }
, { retry: true }
, { retry: 5 }
are shorthands to
disable or configure retries.
However, Defer offers more precise retry strategies.
Fine-tuning your retry strategy
Defer comes with a number of retry parameters. The code below shows you the role of each retry option:
{
// How many retries should we attempt in total?
maxAttempts: 3,
// How close the first retry should be? (in seconds) ?
initialInterval: 30,
// How much randomness should be introduced in the space between retries?
randomizationFactor: 0,5,
// How fast the space between each retry should grow? (exponential back-off)
multiplier: 1,5,
// What should be the max space between 2 retries? (in seconds)
maxInterval: 600,
}
Again, take a look at our retry deep dive for a full discussion and more use cases.
Was this page helpful?