← Назад к вопросам

Как обрабатываются ошибки в NestJS?

1.8 Middle🔥 191 комментариев
#Node.js и JavaScript#Фреймворки и библиотеки

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Обработка ошибок в NestJS

NestJS предоставляет мощный и гибкий механизм обработки ошибок, встроенный в архитектуру фреймворка. Это один из ключевых аспектов надёжного бэкенда.

1. Exception Filters

Exception filters — это основной способ обработки ошибок в NestJS. Они являются слоем между выброшенным исключением и HTTP ответом.

import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const status = exception.getStatus();
    const exceptionResponse = exception.getResponse();

    response.status(status).json({
      statusCode: status,
      message: exceptionResponse,
      timestamp: new Date().toISOString(),
    });
  }
}

Применение на уровне контроллера или приложения:

@UseFilters(HttpExceptionFilter)
@Controller('users')
export class UsersController {
  @Get()
  getUsers() {
    // ...
  }
}

// Или глобально в main.ts
app.useGlobalFilters(new HttpExceptionFilter());

2. Built-in HTTP Exceptions

NestJS имеет набор встроенных исключений для различных HTTP статусов:

import { BadRequestException, NotFoundException, UnauthorizedException } from '@nestjs/common';

@Post('users')
createUser(@Body() createUserDto: CreateUserDto) {
  if (!createUserDto.email) {
    throw new BadRequestException('Email is required');
  }
}

@Get('users/:id')
getUser(@Param('id') id: string) {
  const user = this.usersService.findById(id);
  if (!user) {
    throw new NotFoundException(`User with id ${id} not found`);
  }
  return user;
}

3. Custom Exceptions

Для более сложных сценариев создаются кастомные исключения:

export class InsufficientFundsException extends HttpException {
  constructor(availableFunds: number, requiredFunds: number) {
    super(
      {
        statusCode: 402,
        message: 'Insufficient funds',
        availableFunds,
        requiredFunds,
      },
      402,
    );
  }
}

4. Try-Catch в сервисах

@Injectable()
export class UsersService {
  async createUser(createUserDto: CreateUserDto) {
    try {
      return await this.db.users.create(createUserDto);
    } catch (error) {
      if (error.code === 'UNIQUE_VIOLATION') {
        throw new BadRequestException('User already exists');
      }
      throw new InternalServerErrorException('Failed to create user');
    }
  }
}

5. Interceptors для обработки ошибок

@Injectable()
export class ErrorsInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      catchError(err => {
        throw new InternalServerErrorException();
      }),
    );
  }
}

6. Pipes для валидации

app.useGlobalPipes(new ValidationPipe({
  whitelist: true,
  forbidNonWhitelisted: true,
  transform: true,
}));

Best Practices

  • Не логируй дважды — обработай на одном уровне
  • Безопасность — не передавай внутренние ошибки клиенту
  • Специфичные HTTP коды — используй правильные статусы
  • Глобальные фильтры — для единообразной обработки
  • Структурированное логирование — используй Logger NestJS