Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

+1 371новая вакансия за сутки·54 593вакансии открыты сейчас·Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Новые вакансии в TelegramРаботодателям
Talanto
Вакансии
Компании5 604
РезюмеAIПодготовкаСтатьи
BoostТарифыBoost
Войти

Не нашли подходящее?

Пусть нужная вакансия найдёт вас сама.

  1. Подборка в TelegramНовые вакансии по вашему фильтру — сразу в бота.Подключить
  2. Мэтчи по резюмеЗагрузите резюме — покажем, где вы подходите лучше всего.Загрузить
  3. Сохранить фильтрНастройте поиск один раз и возвращайтесь к новым вакансиям.Настроить
Что нового на TalantoTalanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Для работодателей

Опубликуйте вакансию — отклики придут в ваш кабинет.

  1. Вакансиябесплатно
  2. Откликиконтакты бесплатно
  3. Наймэтапы и интервью

40 компаний публикуют вакансии напрямую · 4 396 кандидатов открыты к предложениям

Разместить вакансию

Популярные направления

Все подборки
  • Python8 800
  • Облачные технологии6 644
  • QA вакансии2 164
  • Android1 317
  • Инженер данных868
  • Продакт-менеджер314

Разработка

  • iOS1 229
  • Backend вакансии1 199
  • AI вакансии548
  • Fullstack вакансии495
  • Frontend вакансии424
  • Mobile вакансии28

По стеку

  • Go5 236
  • Java3 132
  • Kotlin1 120
  • Node.js1 005
  • Rust852
  • .NET659
  • PHP319
  • C++268
  • C#207

DevOps и инфраструктура

  • Kubernetes3 909
  • Linux-инфраструктура2 843
  • DevOps вакансии2 675
  • Terraform / IaC2 175
  • Мониторинг и Observability1 072
  • CI/CD915
  • SRE305
  • Кибербезопасность33

Аналитика и данные

  • Аналитик данных532
  • Data Scientist435
  • Бизнес-аналитик400
  • Системный аналитик68

Другие направления

  • Проджект-менеджер105
  • UI/UX дизайн68
  • Ручное тестирование14

По регионам

  • Вакансии в США25 825
  • Вакансии в Европе10 301
  • Работа в России3 618
  • Вакансии в Канаде2 268

По формату

  • Удалённые вакансии42 661
  • Релокация в США25 825
  • Гибридная работа5 655
  • Офисная работа4 440

По уровню

  • Senior вакансии22 599
  • Middle вакансии11 490
  • Junior вакансии3 852

Сейчас нанимают

Все компании
  • Rakuten189 вакансий
  • Wise187 вакансий
  • ASML164 вакансии
  • Grab134 вакансии
  • Celonis47 вакансий
  • Spotify37 вакансий
  • Infobip28 вакансий
  • Adyen27 вакансий
  • Monzo19 вакансий
  • Darktrace17 вакансий

Вакансии из 344 источников: карьерные страницы компаний и джоб-борды.

КомпанииО насНовостиПубличная офертаУсловия использованияПолитика конфиденциальностиПоддержка
←К теме Express.jsВсе вопросы
Express.jsMiddleКодинг

Как создать кастомный middleware для обработки ошибок в Express?

В закладки
Сначала попробуйте ответить сами30 секунд
Сравнить с ответом ↓

Error middleware в Express определяется строго по четырём параметрам (err, req, res, next), регистрируется последним через app.use() и должен вызывать res.json() без повторного вызова next.

Базовая структура

import { Request, Response, NextFunction } from 'express';

export function errorMiddleware(
  err: Error,
  req: Request,
  res: Response,
  next: NextFunction   // обязателен, даже если не используется
): void {
  console.error(`[${new Date().toISOString()}] ${req.method} ${req.path}`, err);

  const status = (err as any).status ?? (err as any).statusCode ?? 500;
  const message =
    process.env.NODE_ENV === 'production' && status === 500
      ? 'Internal server error'
      : err.message;

  res.status(status).json({ error: message });
}

Кастомный error middleware в Express

Error middleware в Express отличается от обычного тем, что принимает четыре аргумента: (err, req, res, next). Express определяет его именно по сигнатуре — если убрать хотя бы один параметр, функция перестаёт работать как error handler.

Кастомные классы ошибок

// errors/HttpError.ts
export class HttpError extends Error {
  constructor(
    public readonly status: number,
    message: string,
    public readonly code?: string
  ) {
    super(message);
    this.name = 'HttpError';
  }
}

export class NotFoundError extends HttpError {
  constructor(resource = 'Resource') {
    super(404, `${resource} not found`, 'NOT_FOUND');
  }
}

export class ValidationError extends HttpError {
  constructor(
    message: string,
    public readonly fields?: Record<string, string>
  ) {
    super(422, message, 'VALIDATION_ERROR');
  }
}
// routes/users.ts
import { NotFoundError, ValidationError } from '../errors/HttpError';

router.get('/users/:id', asyncHandler(async (req, res) => {
  const { id } = req.params;
  if (!/^\d+$/.test(id)) throw new ValidationError('id must be a number');

  const user = await userService.findById(Number(id));
  if (!user) throw new NotFoundError('User');

  res.json(user);
}));

Полный error middleware с разными типами ошибок

// middleware/errorMiddleware.ts
import { Request, Response, NextFunction } from 'express';
import { HttpError } from '../errors/HttpError';
import { ZodError } from 'zod';

export function errorMiddleware(
  err: unknown,
  req: Request,
  res: Response,
  next: NextFunction
): void {
  // Zod validation error
  if (err instanceof ZodError) {
    res.status(422).json({
      error: 'Validation failed',
      fields: err.errors.map(e => ({ path: e.path.join('.'), message: e.message })),
    });
    return;
  }

  // Кастомные HTTP-ошибки
  if (err instanceof HttpError) {
    res.status(err.status).json({
      error: err.message,
      code: err.code,
    });
    return;
  }

  // pg unique violation
  if ((err as any).code === '23505') {
    res.status(409).json({ error: 'Resource already exists' });
    return;
  }

  // Неизвестная ошибка
  console.error('Unhandled error:', err);
  res.status(500).json({
    error: process.env.NODE_ENV === 'production'
      ? 'Internal server error'
      : (err instanceof Error ? err.message : String(err)),
  });
}

Регистрация в app.ts

import express from 'express';
import { userRouter } from './routes/users';
import { errorMiddleware } from './middleware/errorMiddleware';

const app = express();
app.use(express.json());
app.use('/api/users', userRouter);

// 404 handler — ПЕРЕД error middleware, ПОСЛЕ маршрутов
app.use((req, res) => {
  res.status(404).json({ error: `Route ${req.method} ${req.path} not found` });
});

// Error middleware — ПОСЛЕДНИМ
app.use(errorMiddleware);

export default app;

Подводные камни

  • Сигнатура без 4 параметров: если написать (err, req, res), Express не распознает это как error middleware и ошибки не будут обрабатываться.
  • Регистрация не последней: error middleware должен быть после всех маршрутов и обычных middleware, иначе до него просто не дойдёт выполнение.
  • Не вызывать next() после res.json(): если уже отправили ответ и потом вызовете next(err) — получите «Cannot set headers after they are sent»; проверяйте res.headersSent.
  • Утечка стека ошибок в production: err.stack содержит пути файловой системы и версии зависимостей — никогда не отправляйте его клиенту в боевом окружении.
  • Тип err = any/unknown: в TypeScript err может быть чем угодно (не только Error), поэтому проверяйте через instanceof перед доступом к свойствам.
  • Нет обработки ошибок парсинга JSON: если express.json() получит невалидный JSON, он вызовет next с объектом ошибки типа SyntaxError со статусом 400 — обработайте его явно в error middleware.
  • Отсутствие логирования: молчаливое поглощение ошибок без console.error или внешнего логгера (Pino, Winston) делает отладку production-проблем почти невозможной.

Частые вопросы на собеседовании

  • В чём разница между app.use() и app.get() / app.post()?
  • Какова роль next() в middleware Express? Что происходит, если его не вызвать?
  • Как работает маршрутизация в Express? Как организовать маршруты с помощью express.Router()?
  • Что такое middleware в Express.js? Объясните цикл запрос-ответ (request-response cycle).

Типичные ошибки

  • Дает общий ответ про Node.js и не называет конкретные API Express.js.
  • Не объясняет, где в lifecycle находится кастомный error-handling middleware.
  • Не разделяет validation, authorization, business logic и persistence.
  • Игнорирует ошибки, лимиты входных данных, observability и тестирование.

Что проверяет интервьюер

  • Может объяснить кастомный error-handling middleware на примере кода.
  • Называет ключевые API: app.use(errorHandler).
  • Использует точные API Express.js, а не вымышленные hooks/decorators/methods.
  • Видит production-риски: безопасность, отказоустойчивость, логирование и тесты.

Как вы знаете этот вопрос?

Проверить себя по теме Express.js →

Источники

  • https://expressjs.com/en/guide/error-handling.html
  • https://expressjs.com/en/5x/api.html
←Предыдущий вопросКак разобрать тело запроса в формате JSON и URL-encoded в Express?Следующий вопрос→Как подключить Express к базе данных (PostgreSQL, MongoDB)?

Связанные темы

Express.jsapi-designerror-handling