Проверяет понимание обработки ошибок в EventEmitter Node.js и умение изолировать сбой одного слушателя, чтобы не ломать остальные.
EventEmitter в Node.js вызывает слушателей синхронно в порядке подписки. Если один из них бросает исключение, оно прерывает цикл emit, и последующие слушатели не выполнятся. Чтобы изолировать сбой, нужно перехватывать ошибку внутри самого обработчика, а не позволять ей всплывать наружу.
Для синхронного кода достаточно обернуть тело функции в try/catch и залогировать ошибку. Это гарантирует, что emit продолжит вызывать остальных слушателей.
const { EventEmitter } = require('events');
const emitter = new EventEmitter();
emitter.on('data', (payload) => {
try {
// может бросить исключение
riskyOperation(payload);
} catch (err) {
console.error('Listener A failed:', err);
}
});
emitter.on('data', (payload) => {
console.log('Listener B still runs');
});
emitter.emit('data', { id: 1 });Если слушатель асинхронный, try/catch внутри async-функции не поймает ошибку, если она возникнет после await и не будет обёрнута. Нужно либо оборачивать весь async-код в try/catch, либо использовать .catch() на промисах. Также важно помнить, что emit не ждёт завершения промисов, поэтому ошибки в них не влияют на синхронный цикл emit, но могут привести к unhandledRejection.
emitter.on('data', async (payload) => {
try {
await asyncRiskyOperation(payload);
} catch (err) {
console.error('Async listener failed:', err);
}
});
// Альтернатива через .catch()
emitter.on('data', (payload) => {
asyncRiskyOperation(payload).catch((err) => {
console.error('Async listener failed:', err);
});
});Чтобы не дублировать try/catch, можно создать обёртку-хелпер, которая принимает функцию-слушателя и возвращает безопасную версию с логированием.
function safeListener(fn, logger = console) {
return (...args) => {
try {
const result = fn(...args);
if (result && typeof result.catch === 'function') {
result.catch((err) => logger.error('Listener error:', err));
}
} catch (err) {
logger.error('Listener error:', err);
}
};
}
emitter.on('data', safeListener(riskyHandler));Такой подход полезен в системах с множеством подписчиков: один сбойный обработчик не должен блокировать остальные, а ошибка должна быть видна в логах для диагностики. Применяйте изоляцию ошибок в EventEmitter везде, где слушатели независимы и их отказ не должен влиять на другие части приложения.
Уровень
Рейтинг:
4
Сложность:
5
Навыки
JavaScript
Node.js
Ключевые слова
Подпишись на React Developer в телеграм
Frontend developer
Ментор по Frontend
Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства
Записаться на консультацию