Elegant Handling of async/await Exceptions in JavaScript
This article examines why try‑catch is often overused for async/await errors, outlines common scenarios that cause request failures, and presents two cleaner alternatives—using Promise .catch with conditional logic and the lightweight await‑to‑js utility—to simplify error handling and reduce code redundancy.
Introduction
Many projects handle async/await exceptions with repetitive try‑catch blocks, which can clutter code and create redundancy. While try‑catch works, it often makes the logic harder to follow.
When Do Request Exceptions Occur?
Async requests may fail due to network disconnections or timeouts caused by slow connections.
When Should Exceptions Be Handled?
When an async request throws, JavaScript’s single‑threaded nature stops subsequent code execution, so handling the error allows the program to continue.
Serial Async Requests
try {
// Get list
const list = await getList(params);
// Get details using first item
const info = await getListById(list[0]?.id);
} catch {}If the first request fails, subsequent requests will also fail, necessitating error handling.
Managing Loading State
loading.value = true;
try {
const list = await getList(params);
} finally {
loading.value = false;
}Without a try‑catch, a failed request could leave the UI stuck in a loading state, so the finally block ensures the loading flag is reset.
Cleaner Handling Methods
Using Promise .catch
Since await returns a Promise, you can attach .catch to handle errors and use an if statement to exit early, avoiding unnecessary try‑catch blocks.
loading.value = true;
let res = await getList().catch(() => (loading.value = false));
if (!res) return;
// Continue with successful responseawait‑to‑js Utility
The await-to-js library provides a to function that returns a tuple [err, data] , eliminating the need for try‑catch.
/**
* @param { Promise } promise
* @param { Object= } errorExt - Additional info for the error object
* @return { Promise }
*/
export function to
(
promise: Promise
,
errorExt?: object
): Promise<[U, undefined] | [null, T]> {
return promise
.then<[null, T]>((data: T) => [null, data])
.catch<[U, undefined]>((err: U) => {
if (errorExt) {
const parsedError = Object.assign({}, err, errorExt);
return [parsedError, undefined];
}
return [err, undefined];
});
}
export default to;Usage example:
import to from 'await-to-js';
const [err, data] = await to(getList(params));
if (err) return;
// Process dataConclusion
The article demonstrates two concise approaches—Promise .catch with conditional checks and the await-to-js helper—to replace repetitive try‑catch blocks, resulting in cleaner, more maintainable async/await code.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.