Migrate to a monorepo structure (#2909)
This commit is contained in:
@ -0,0 +1,17 @@
|
||||
import { ExceptionHandlerDriverInterface } from 'src/integrations/exception-handler/interfaces';
|
||||
|
||||
export class ExceptionHandlerConsoleDriver
|
||||
implements ExceptionHandlerDriverInterface
|
||||
{
|
||||
captureException(exception: unknown) {
|
||||
console.group('Exception Captured');
|
||||
console.error(exception);
|
||||
console.groupEnd();
|
||||
}
|
||||
|
||||
captureMessage(message: string): void {
|
||||
console.group('Message Captured');
|
||||
console.info(message);
|
||||
console.groupEnd();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { ProfilingIntegration } from '@sentry/profiling-node';
|
||||
|
||||
import {
|
||||
ExceptionHandlerDriverInterface,
|
||||
ExceptionHandlerSentryDriverFactoryOptions,
|
||||
} from 'src/integrations/exception-handler/interfaces';
|
||||
|
||||
export class ExceptionHandlerSentryDriver
|
||||
implements ExceptionHandlerDriverInterface
|
||||
{
|
||||
constructor(options: ExceptionHandlerSentryDriverFactoryOptions['options']) {
|
||||
Sentry.init({
|
||||
dsn: options.dns,
|
||||
integrations: [
|
||||
// enable HTTP calls tracing
|
||||
new Sentry.Integrations.Http({ tracing: true }),
|
||||
// enable Express.js middleware tracing
|
||||
new Sentry.Integrations.Express({ app: options.serverInstance }),
|
||||
new Sentry.Integrations.GraphQL(),
|
||||
new Sentry.Integrations.Postgres({
|
||||
usePgNative: true,
|
||||
}),
|
||||
new ProfilingIntegration(),
|
||||
],
|
||||
tracesSampleRate: 1.0,
|
||||
profilesSampleRate: 1.0,
|
||||
environment: options.debug ? 'development' : 'production',
|
||||
debug: options.debug,
|
||||
});
|
||||
}
|
||||
|
||||
captureException(exception: Error) {
|
||||
Sentry.captureException(exception);
|
||||
}
|
||||
|
||||
captureMessage(message: string) {
|
||||
Sentry.captureMessage(message);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
export const EXCEPTION_HANDLER_DRIVER = Symbol('EXCEPTION_HANDLER_DRIVER');
|
||||
@ -0,0 +1,25 @@
|
||||
import {
|
||||
ConfigurableModuleBuilder,
|
||||
FactoryProvider,
|
||||
ModuleMetadata,
|
||||
} from '@nestjs/common';
|
||||
|
||||
import { ExceptionHandlerModuleOptions } from './interfaces';
|
||||
|
||||
export const {
|
||||
ConfigurableModuleClass,
|
||||
MODULE_OPTIONS_TOKEN,
|
||||
OPTIONS_TYPE,
|
||||
ASYNC_OPTIONS_TYPE,
|
||||
} = new ConfigurableModuleBuilder<ExceptionHandlerModuleOptions>({
|
||||
moduleName: 'ExceptionHandlerModule',
|
||||
})
|
||||
.setClassMethodName('forRoot')
|
||||
.build();
|
||||
|
||||
export type ExceptionHandlerModuleAsyncOptions = {
|
||||
useFactory: (
|
||||
...args: any[]
|
||||
) => ExceptionHandlerModuleOptions | Promise<ExceptionHandlerModuleOptions>;
|
||||
} & Pick<ModuleMetadata, 'imports'> &
|
||||
Pick<FactoryProvider, 'inject'>;
|
||||
@ -0,0 +1,39 @@
|
||||
import { HttpAdapterHost } from '@nestjs/core';
|
||||
|
||||
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
||||
import { OPTIONS_TYPE } from 'src/integrations/exception-handler/exception-handler.module-definition';
|
||||
import { ExceptionHandlerDriver } from 'src/integrations/exception-handler/interfaces';
|
||||
|
||||
/**
|
||||
* ExceptionHandler Module factory
|
||||
* @param environment
|
||||
* @returns ExceptionHandlerModuleOptions
|
||||
*/
|
||||
export const exceptionHandlerModuleFactory = async (
|
||||
environmentService: EnvironmentService,
|
||||
adapterHost: HttpAdapterHost,
|
||||
): Promise<typeof OPTIONS_TYPE> => {
|
||||
const driverType = environmentService.getExceptionHandlerDriverType();
|
||||
|
||||
switch (driverType) {
|
||||
case ExceptionHandlerDriver.Console: {
|
||||
return {
|
||||
type: ExceptionHandlerDriver.Console,
|
||||
};
|
||||
}
|
||||
case ExceptionHandlerDriver.Sentry: {
|
||||
return {
|
||||
type: ExceptionHandlerDriver.Sentry,
|
||||
options: {
|
||||
dns: environmentService.getSentryDSN() ?? '',
|
||||
serverInstance: adapterHost.httpAdapter.getInstance(),
|
||||
debug: environmentService.isDebugMode(),
|
||||
},
|
||||
};
|
||||
}
|
||||
default:
|
||||
throw new Error(
|
||||
`Invalid exception capturer driver type (${driverType}), check your .env file`,
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,60 @@
|
||||
import { DynamicModule, Global, Module } from '@nestjs/common';
|
||||
|
||||
import { ExceptionHandlerSentryDriver } from 'src/integrations/exception-handler/drivers/sentry.driver';
|
||||
import { ExceptionHandlerConsoleDriver } from 'src/integrations/exception-handler/drivers/console.driver';
|
||||
|
||||
import { ExceptionHandlerService } from './exception-handler.service';
|
||||
import { ExceptionHandlerDriver } from './interfaces';
|
||||
import { EXCEPTION_HANDLER_DRIVER } from './exception-handler.constants';
|
||||
import {
|
||||
ConfigurableModuleClass,
|
||||
OPTIONS_TYPE,
|
||||
ASYNC_OPTIONS_TYPE,
|
||||
} from './exception-handler.module-definition';
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
providers: [ExceptionHandlerService],
|
||||
exports: [ExceptionHandlerService],
|
||||
})
|
||||
export class ExceptionHandlerModule extends ConfigurableModuleClass {
|
||||
static forRoot(options: typeof OPTIONS_TYPE): DynamicModule {
|
||||
const provider = {
|
||||
provide: EXCEPTION_HANDLER_DRIVER,
|
||||
useValue:
|
||||
options.type === ExceptionHandlerDriver.Console
|
||||
? new ExceptionHandlerConsoleDriver()
|
||||
: new ExceptionHandlerSentryDriver(options.options),
|
||||
};
|
||||
const dynamicModule = super.forRoot(options);
|
||||
|
||||
return {
|
||||
...dynamicModule,
|
||||
providers: [...(dynamicModule.providers ?? []), provider],
|
||||
};
|
||||
}
|
||||
|
||||
static forRootAsync(options: typeof ASYNC_OPTIONS_TYPE): DynamicModule {
|
||||
const provider = {
|
||||
provide: EXCEPTION_HANDLER_DRIVER,
|
||||
useFactory: async (...args: any[]) => {
|
||||
const config = await options?.useFactory?.(...args);
|
||||
|
||||
if (!config) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return config.type === ExceptionHandlerDriver.Console
|
||||
? new ExceptionHandlerConsoleDriver()
|
||||
: new ExceptionHandlerSentryDriver(config.options);
|
||||
},
|
||||
inject: options.inject || [],
|
||||
};
|
||||
const dynamicModule = super.forRootAsync(options);
|
||||
|
||||
return {
|
||||
...dynamicModule,
|
||||
providers: [...(dynamicModule.providers ?? []), provider],
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
|
||||
import { ExceptionHandlerService } from 'src/integrations/exception-handler/exception-handler.service';
|
||||
|
||||
import { EXCEPTION_HANDLER_DRIVER } from './exception-handler.constants';
|
||||
|
||||
describe('ExceptionHandlerService', () => {
|
||||
let service: ExceptionHandlerService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
ExceptionHandlerService,
|
||||
{
|
||||
provide: EXCEPTION_HANDLER_DRIVER,
|
||||
useValue: {},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<ExceptionHandlerService>(ExceptionHandlerService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,17 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
|
||||
import { ExceptionHandlerDriverInterface } from 'src/integrations/exception-handler/interfaces';
|
||||
|
||||
import { EXCEPTION_HANDLER_DRIVER } from './exception-handler.constants';
|
||||
|
||||
@Injectable()
|
||||
export class ExceptionHandlerService {
|
||||
constructor(
|
||||
@Inject(EXCEPTION_HANDLER_DRIVER)
|
||||
private driver: ExceptionHandlerDriverInterface,
|
||||
) {}
|
||||
|
||||
captureException(exception: unknown) {
|
||||
this.driver.captureException(exception);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
export interface ExceptionHandlerDriverInterface {
|
||||
captureException(exception: unknown): void;
|
||||
captureMessage(message: string): void;
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
import { Router } from 'express';
|
||||
|
||||
export enum ExceptionHandlerDriver {
|
||||
Sentry = 'sentry',
|
||||
Console = 'console',
|
||||
}
|
||||
|
||||
export interface ExceptionHandlerSentryDriverFactoryOptions {
|
||||
type: ExceptionHandlerDriver.Sentry;
|
||||
options: {
|
||||
dns: string;
|
||||
serverInstance: Router;
|
||||
debug?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ExceptionHandlerDriverFactoryOptions {
|
||||
type: ExceptionHandlerDriver.Console;
|
||||
}
|
||||
|
||||
export type ExceptionHandlerModuleOptions =
|
||||
| ExceptionHandlerSentryDriverFactoryOptions
|
||||
| ExceptionHandlerDriverFactoryOptions;
|
||||
@ -0,0 +1,2 @@
|
||||
export * from './exception-handler.interface';
|
||||
export * from './exception-handler-driver.interface';
|
||||
Reference in New Issue
Block a user