This commit is contained in:
2026-02-06 11:52:30 +03:00
parent 1812de0baf
commit fd7bf76abd
4 changed files with 289 additions and 6 deletions

View File

@ -15,12 +15,20 @@ import { UsersModule } from '../users/users.module';
PassportModule.register({ defaultStrategy: 'jwt' }),
JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
secret: configService.get('JWT_SECRET'),
signOptions: {
expiresIn: '7d',
},
}),
useFactory: async (configService: ConfigService) => {
const secret = configService.get<string>('JWT_SECRET');
if (!secret || secret.trim() === '') {
throw new Error(
'JWT_SECRET is not set or empty. Set it in .env and run Docker with: docker compose --env-file .env up -d',
);
}
return {
secret: secret.trim(),
signOptions: {
expiresIn: '7d',
},
};
},
inject: [ConfigService],
}),
UsersModule,

View File

@ -0,0 +1,48 @@
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
HttpStatus,
Logger,
} from '@nestjs/common';
import { Request, Response } from 'express';
/**
* Логирует все необработанные ошибки в консоль (видны в docker logs coursecraft-api).
* Помогает диагностировать 500 при запуске в Docker.
*/
@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
private readonly logger = new Logger(AllExceptionsFilter.name);
catch(exception: unknown, host: ArgumentsHost): void {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status =
exception instanceof HttpException
? exception.getStatus()
: HttpStatus.INTERNAL_SERVER_ERROR;
const message =
exception instanceof HttpException
? exception.getResponse()
: exception instanceof Error
? exception.message
: 'Internal server error';
this.logger.error(
`${request.method} ${request.url}${status}`,
exception instanceof Error ? exception.stack : String(exception),
);
response.status(status).json({
statusCode: status,
message: typeof message === 'object' && message && 'message' in message
? (message as { message: string }).message
: message,
});
}
}

View File

@ -4,11 +4,14 @@ import { ConfigService } from '@nestjs/config';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import helmet from 'helmet';
import { AppModule } from './app.module';
import { AllExceptionsFilter } from './common/all-exceptions.filter';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const configService = app.get(ConfigService);
app.useGlobalFilters(new AllExceptionsFilter());
// Security
app.use(helmet());