Загрузка…
Загрузка…
Node.js · junior · сложность 3
Как опытный технический интервьюер, я часто ищу полное понимание того, как создавать надежные и надежные приложения. Обработка ошибок в асинхронном Node.js является краеугольным камнем этого подхода, поскольку природа неблокирующего ввода-вывода создает уникальные проблемы по сравнению с синхронным программированием.
Давайте разберем лучшие практики обработки ошибок в асинхронных приложениях Node.js.
В Node.js большая часть логики вашего приложения включает асинхронные операции, такие как получение данных из базы данных, вызовы API или чтение файлов. Когда эти операции сталкиваются с проблемами, они «выбрасывают» ошибки (или, точнее, «отклоняют» обещания). Правильное обнаружение этих ошибок и реагирование на них имеет решающее значение для стабильности приложения, удобства работы пользователей и простоты отладки.
try...catch
с
async/await
async/await
— это современный синтаксис JavaScript, построенный на основе Promises и предназначенный для того, чтобы асинхронный код выглядел и вел себя как синхронный код. Этот «синтаксический сахар» позволяет нам использовать знакомые
try...catch
блок для обработки ошибок асинхронных операций.
async
Функция:** Ан
async
функция всегда возвращает обещание.
await
Ключевое слово:** Когда
await
используется внутри
async
функции, он приостанавливает выполнение этой функции до тех пор, пока обещание, которого он ожидает, либо не разрешится (успешно), либо не будет отклонено (не выполнено).
try...catch
:** Если Обещания ждут
await
отклоняет,
await
фактически «выбрасывает» это отклонение как синхронную ошибку. Это позволяет окружающему
try...catch
блок, чтобы корректно захватить и обработать его, как это было бы с синхронной ошибкой.
Представьте, что вы печете торт (
async
функция). Ты
await
духовку для предварительного разогрева. Если сломалась духовка(
Promise rejection
), вы не просто ждете бесконечно; проблема немедленно брошена вам, и ваш
try...catch
«Рецепт» подсказывает, что делать дальше – возможно, попробовать другую духовку или заказать готовый торт.
async function fetchData(url) {
try {
console.log(`Attempting to fetch data from: ${url}`);
// Simulate a network request that might fail
const response = await new Promise((resolve, reject) => {
setTimeout(() => {
if (url === " {
resolve({ data: "Important info" });
} else {
reject(new Error("Failed to fetch data: Invalid URL or network issue."));
}
}, 1000); // Simulate network latency
});
console.log("Data fetched successfully:", response.data);
return response.data;
} catch (error) {
// This block catches errors from the awaited Promise rejection
console.error("Error in fetchData:", error.message);
// Best practice: Re-throw or return a specific error/value
throw new Error(`Could not process request: ${error.message}`);
}
}
// --- Usage Examples ---
// 1. Successful scenario
(async () => {
console.log("\n--- Scenario 1: Successful Fetch ---");
try {
const data = await fetchData("
console.log("Application received data:", data);
} catch (appError) {
console.error("Application caught error:", appError.message);
}
})();
// 2. Failure scenario
(async () => {
console.log("\n--- Scenario 2: Failed Fetch ---");
try {
const data = await fetchData("
console.log("Application received data:", data); // This line won't be reached
} catch (appError) {
// The error thrown from fetchData's catch block is caught here
console.error("Application caught error:", appError.message);
}
})();Ключевой вывод:
try...catch
с
async/await
— это основной и предпочтительный метод обработки ошибок в современном асинхронном коде Node.js в рамках определенного потока выполнения.
«Необработанное отклонение промиса» происходит, когда промис отклоняется (терпит неудачу), но нет
.catch()
обработчик или
try...catch
блок (в
async
функция), связанная с этим обещанием, для явной обработки ошибки.
Традиционно в Node.js необработанный отказ от обещания регистрировался с предупреждением и в конечном итоге приводил к автоматическому завершению процесса, что может быть очень сложно отладить. Начиная с Node.js версии 7.0, необработанные отклонения обещаний приводят к
UnhandledPromiseRejectionWarning
. Начиная с Node.js v15, если происходит необработанное отклонение обещания, процесс Node.js завершается по умолчанию (как неперехваченное исключение), если только он не будет обработан явно. Это изменение было внесено для предотвращения продолжения работы приложений в неопределенном или потенциально поврежденном состоянии.
Node.js предоставляет глобальный прослушиватель событий на
process
объект для этих случаев:
process.on('unhandledRejection', (reason, promise) => {
console.error('--- Unhandled Promise Rejection ---');
console.error('Reason:', reason);
console.error('Promise:', promise);
// Log the error, perform graceful shutdown, then exit.
// In a production app, you might send alerts, clean up resources, etc.
process.exit(1); // Exit with a non-zero code to indicate an error
});Представьте, что вы отправили письмо (
Promise
) но не указал обратный адрес. Если письмо не может быть доставлено (
rejection
), оно теряется в почтовой системе без вашего ведома, если только в почтовой службе нет глобального отдела «потерянной почты», который помечает это. Твой
unhandledRejection
обработчик — это глобальный отдел «потерянной почты».
// Сначала настраиваем глобальный обработчик unhandledRejection
process.on('unhandledRejection', (причина, обещание) => {
console.error('!!! КРИТИЧЕСКОЕ: Обнаружен необработанный отказ от обещания !!!');
console.error('Сведения об ошибке:', причина);
## Итог
Ключевой вывод для интервью: Обсудите лучшие практики обработки ошибок в асинхронных приложениях Node.js, в частности, о «try...catch» с