Browse Source

feat: add filter for exception handler

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/5444/head
Pranav C 2 years ago
parent
commit
1b4815138c
  1. 15
      packages/nocodb-nest/src/app.module.ts
  2. 7
      packages/nocodb-nest/src/filters/global-exception/global-exception.filter.spec.ts
  3. 61
      packages/nocodb-nest/src/filters/global-exception/global-exception.filter.ts
  4. 18
      packages/nocodb-nest/src/helpers/catchError.ts

15
packages/nocodb-nest/src/app.module.ts

@ -1,5 +1,7 @@
import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';
import { Connection } from './connection/connection'; import { Connection } from './connection/connection';
import { GlobalExceptionFilter } from './filters/global-exception/global-exception.filter';
import { AuthModule } from './modules/auth/auth.module'; import { AuthModule } from './modules/auth/auth.module';
import { ExtractProjectIdMiddleware } from './middlewares/extract-project-id/extract-project-id.middleware'; import { ExtractProjectIdMiddleware } from './middlewares/extract-project-id/extract-project-id.middleware';
import { UsersModule } from './modules/users/users.module'; import { UsersModule } from './modules/users/users.module';
@ -8,7 +10,7 @@ import { MetaService } from './meta/meta.service';
import { UtilsModule } from './modules/utils/utils.module'; import { UtilsModule } from './modules/utils/utils.module';
import { ProjectsModule } from './modules/projects/projects.module'; import { ProjectsModule } from './modules/projects/projects.module';
import { JwtStrategy } from './strategies/jwt.strategy'; import { JwtStrategy } from './strategies/jwt.strategy';
import { AuthGuard } from '@nestjs/passport'; // import { AuthGuard } from '@nestjs/passport';
import { TablesModule } from './modules/tables/tables.module'; import { TablesModule } from './modules/tables/tables.module';
import { ViewsModule } from './modules/views/views.module'; import { ViewsModule } from './modules/views/views.module';
import { FiltersModule } from './modules/filters/filters.module'; import { FiltersModule } from './modules/filters/filters.module';
@ -90,7 +92,16 @@ import { PluginsModule } from './modules/plugins/plugins.module';
PluginsModule, PluginsModule,
], ],
controllers: [], controllers: [],
providers: [Connection, MetaService, JwtStrategy, ExtractProjectIdMiddleware], providers: [
{
provide: APP_FILTER,
useClass: GlobalExceptionFilter,
},
Connection,
MetaService,
JwtStrategy,
ExtractProjectIdMiddleware,
],
exports: [Connection, MetaService], exports: [Connection, MetaService],
}) })
export class AppModule { export class AppModule {

7
packages/nocodb-nest/src/filters/global-exception/global-exception.filter.spec.ts

@ -0,0 +1,7 @@
import { GlobalExceptionFilter } from './global-exception.filter';
describe('GlobalExceptionFilter', () => {
it('should be defined', () => {
expect(new GlobalExceptionFilter()).toBeDefined();
});
});

61
packages/nocodb-nest/src/filters/global-exception/global-exception.filter.ts

@ -0,0 +1,61 @@
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
import { Response } from 'express';
import {
AjvError,
BadRequest,
extractDBError,
Forbidden,
InternalServerError,
NotFound,
NotImplemented,
Unauthorized,
} from 'src/helpers/catchError';
@Catch()
export class GlobalExceptionFilter implements ExceptionFilter {
catch(exception: any, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
// todo: error log
const dbError = extractDBError(exception);
if (dbError) {
return response.status(400).json(dbError);
}
if (exception instanceof BadRequest) {
return response.status(400).json({ msg: exception.message });
} else if (exception instanceof Unauthorized) {
return response.status(401).json({ msg: exception.message });
} else if (exception instanceof Forbidden) {
return response.status(403).json({ msg: exception.message });
} else if (exception instanceof NotFound) {
return response.status(404).json({ msg: exception.message });
} else if (exception instanceof InternalServerError) {
return response.status(500).json({ msg: exception.message });
} else if (exception instanceof NotImplemented) {
return response.status(501).json({ msg: exception.message });
} else if (exception instanceof AjvError) {
return response
.status(400)
.json({ msg: exception.message, errors: exception.errors });
}
// handle different types of exceptions
if (exception instanceof HttpException) {
response.status(exception.getStatus()).json(exception.getResponse());
} else {
response.status(500).json({
statusCode: 500,
message: 'Internal server error',
});
}
}
}

18
packages/nocodb-nest/src/helpers/catchError.ts

@ -1,6 +1,6 @@
import type { ErrorObject } from 'ajv'; import type { ErrorObject } from 'ajv';
enum DBError { export enum DBError {
TABLE_EXIST = 'TABLE_EXIST', TABLE_EXIST = 'TABLE_EXIST',
TABLE_NOT_EXIST = 'TABLE_NOT_EXIST', TABLE_NOT_EXIST = 'TABLE_NOT_EXIST',
COLUMN_EXIST = 'COLUMN_EXIST', COLUMN_EXIST = 'COLUMN_EXIST',
@ -11,7 +11,7 @@ enum DBError {
} }
// extract db errors using database error code // extract db errors using database error code
function extractDBError(error): { export function extractDBError(error): {
type: DBError; type: DBError;
message: string; message: string;
info: any; info: any;
@ -419,19 +419,19 @@ export default function (
}; };
} }
class BadRequest extends Error {} export class BadRequest extends Error {}
class Unauthorized extends Error {} export class Unauthorized extends Error {}
class Forbidden extends Error {} export class Forbidden extends Error {}
class NotFound extends Error {} export class NotFound extends Error {}
class InternalServerError extends Error {} export class InternalServerError extends Error {}
class NotImplemented extends Error {} export class NotImplemented extends Error {}
class AjvError extends Error { export class AjvError extends Error {
constructor(param: { message: string; errors: ErrorObject[] }) { constructor(param: { message: string; errors: ErrorObject[] }) {
super(param.message); super(param.message);
this.errors = param.errors; this.errors = param.errors;

Loading…
Cancel
Save