Шаблони обробки помилок у Node.js
Обробка помилок у Node.js
Правильна обробка помилок є критично важливою в Node.js. Неперехоплені помилки призводять до аварійного завершення роботи сервера. Node.js має кілька шаблонів для обробки помилок, залежно від стилю коду.
Типи помилок
| Тип | Опис |
|---|---|
| Операційні помилки | Очікувані: з'єднання з БД не вдалося, недійсні дані, файл не знайдено |
| Помилки програміста | Помилки: TypeError, ReferenceError, неправильні аргументи |
Операційні помилки слід обробляти коректно; помилки програміста зазвичай вимагають перезапуску.
1. Колбеки (конвенція Node.js з обробкою помилок)
js
fs.readFile('./file.txt', 'utf8', (err, data) => {
if (err) {
console.error('Не вдалося прочитати:', err.message);
return; // обробити та зупинити
}
console.log(data);
});Перший аргумент завжди є помилкою (або null, якщо її немає).
2. Проміси
js
fetchUser(id)
.then(user => process(user))
.catch(err => console.error('Помилка:', err.message))
.finally(() => cleanup());3. async/await з try/catch
js
async function getUser(id) {
try {
const user = await fetchUser(id);
const posts = await fetchPosts(user.id);
return { user, posts };
} catch (err) {
console.error('Не вдалося:', err.message);
throw err; // повторно викинути, якщо потрібно
}
}4. Обробка помилок в Express
js
// Обгортка асинхронних обробників маршрутів
function asyncHandler(fn) {
return (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
}
app.get('/user/:id', asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id);
if (!user) throw new Error('Користувача не знайдено');
res.json(user);
}));
// Централізований обробник помилок
app.use((err, req, res, next) => {
const status = err.statusCode || 500;
res.status(status).json({
error: err.message,
stack: process.env.NODE_ENV === 'development' ? err.stack : undefined
});
});5. Класі помилок
js
class AppError extends Error {
constructor(message, statusCode = 500) {
super(message);
this.statusCode = statusCode;
this.name = 'AppError';
Error.captureStackTrace(this, this.constructor);
}
}
class NotFoundError extends AppError {
constructor(resource) {
super(`${resource} не знайдено`, 404);
}
}
// Використання
throw new NotFoundError('Користувача');6. Глобальні неперехоплені помилки
js
// Неперехоплені відхилення промісів (Node.js 15+ за замовчуванням аварійно завершує роботу)
process.on('unhandledRejection', (reason, promise) => {
console.error('Неперехоплене відхилення:', reason);
// Логувати та коректно завершити роботу
process.exit(1);
});
// Неперехоплені синхронні виключення
process.on('uncaughtException', (err) => {
console.error('Неперехоплене виключення:', err);
process.exit(1); // потрібно завершити! стан пошкоджено
});Найкращі практики
- Завжди обробляйте помилки — ніколи не ігноруйте їх безшумно
- Використовуйте кастомні класи помилок з кодами статусу
- Централізуйте обробку помилок в Express за допомогою проміжного програмного забезпечення для обробки помилок
- Логуйте помилки з контекстом (ID запиту, ID користувача, стек-трасу)
- Ніколи не викидайте в
process.on('uncaughtException')— коректно завершуйте роботу - Використовуйте
Promise.allSettled()коли деякі відмови є прийнятними
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.