Skip to content

Commit

Permalink
fix(exception): exception-filter loader (#211)
Browse files Browse the repository at this point in the history
* fix(exception): exception-filter loader

* refactor(exception): better exception filter match logic

* refactor(exception): add util function matchExceptionFilterClazz
  • Loading branch information
noahziheng authored Oct 20, 2022
1 parent 2931407 commit 1402d8a
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 25 deletions.
1 change: 1 addition & 0 deletions src/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const EXCEPTION_FILENAME = 'exception.json';

export const DEFAULT_LOADER_LIST_WITH_ORDER = [
'exception',
'exception-filter',
'plugin-config',
'plugin-meta',
'framework-config',
Expand Down
2 changes: 1 addition & 1 deletion src/exception/decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const Catch = (targetErr?: string|Constructable<Error>): ClassDecorator =
Reflect.defineMetadata(EXCEPTION_FILTER_METADATA_KEY, {
targetErr: targetErr ?? EXCEPTION_FILTER_DEFAULT_SYMBOL,
}, target);
Reflect.defineMetadata(HOOK_FILE_LOADER, { loader: 'exception_filter' }, target);
Reflect.defineMetadata(HOOK_FILE_LOADER, { loader: 'exception-filter' }, target);
Injectable()(target);
};
};
31 changes: 13 additions & 18 deletions src/exception/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,30 @@ import { EXCEPTION_FILTER_DEFAULT_SYMBOL, EXCEPTION_FILTER_MAP_INJECT_ID } from
import { ArtusStdError } from './impl';
import { ExceptionFilterMapType, ExceptionFilterType } from './types';

export const matchExceptionFilter = (err: Error, container: Container): ExceptionFilterType | null => {
export const matchExceptionFilterClazz = (err: Error, container: Container): Constructable<ExceptionFilterType> | null => {
const filterMap: ExceptionFilterMapType = container.get(EXCEPTION_FILTER_MAP_INJECT_ID, {
noThrow: true,
});
if (!filterMap) {
return null;
}
let targetFilterClazz: Constructable<ExceptionFilterType>;
// handle ArtusStdError with code simply
let targetFilterClazz: Constructable<ExceptionFilterType> | null = null;
if (err instanceof ArtusStdError) {
// handle ArtusStdError with code simply
targetFilterClazz = filterMap.get(err.code);
}
if (!targetFilterClazz) {
// handler other Exception by Clazz
for (const errorClazz of filterMap.keys()) {
if (typeof errorClazz === 'string' || typeof errorClazz === 'symbol') {
continue;
}
if (err instanceof errorClazz) {
targetFilterClazz = filterMap.get(errorClazz);
break;
}
}
}
if (!targetFilterClazz && filterMap.has(EXCEPTION_FILTER_DEFAULT_SYMBOL)) {
} else if (filterMap.has(err['constructor'] as Constructable<Error>)) {
// handle CustomErrorClazz
targetFilterClazz = filterMap.get(err['constructor'] as Constructable<Error>);
} else if (filterMap.has(EXCEPTION_FILTER_DEFAULT_SYMBOL)) {
// handle default ExceptionFilter
targetFilterClazz = filterMap.get(EXCEPTION_FILTER_DEFAULT_SYMBOL);
}
return targetFilterClazz;
};

export const matchExceptionFilter = (err: Error, container: Container): ExceptionFilterType | null => {
const filterClazz = matchExceptionFilterClazz(err, container);

// return the instance of exception filter
return targetFilterClazz ? container.get(targetFilterClazz) : null;
return filterClazz ? container.get(filterClazz) : null;
};
2 changes: 1 addition & 1 deletion src/loader/impl/exception_filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ArtusStdError, EXCEPTION_FILTER_DEFAULT_SYMBOL, EXCEPTION_FILTER_MAP_IN
import { Constructable } from '@artus/injection';
import { ExceptionFilterMapType, ExceptionFilterType, ExceptionIdentifier } from '../../exception/types';

@DefineLoader('exception_filter')
@DefineLoader('exception-filter')
class ExceptionFilterLoader extends ModuleLoader {
async load(item: ManifestItem) {
// Get or Init Exception Filter Map
Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/app_koa_with_ts/src/filter/default.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Catch, ExceptionFilterType } from '../../../../../src';

@Catch()
export class MockExceptionFilter implements ExceptionFilterType {
async catch(_err: Error): Promise<void> {
// Empty filter
}
}
2 changes: 1 addition & 1 deletion test/fixtures/exception_filter/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ async function main() {
path: path.resolve(__dirname, './filter'),
extname: '.ts',
filename: 'filter.ts',
loader: 'exception_filter',
loader: 'exception-filter',
loaderState: {
exportNames: [
'TestDefaultExceptionHandler',
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/exception_invalid_filter/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ async function main() {
path: path.resolve(__dirname, './filter'),
extname: '.ts',
filename: 'filter.ts',
loader: 'exception_filter',
loader: 'exception-filter',
loaderState: {
exportNames: [
'TestInvalidFilter',
Expand Down
7 changes: 4 additions & 3 deletions test/scanner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,21 @@ describe('test/scanner.test.ts', () => {
expect(manifest).toBeDefined();
expect(manifest.items).toBeDefined();
// console.log('manifest', manifest);
expect(manifest.items.length).toBe(10);
expect(manifest.items.length).toBe(11);

expect(manifest.items.find(item => item.filename === 'not_to_be_scanned_file.ts')).toBeFalsy();

expect(manifest.items.filter(item => item.loader === 'plugin-config').length).toBe(0);
expect(manifest.items.filter(item => item.loader === 'plugin-meta').length).toBe(1);
expect(manifest.items.filter(item => item.loader === 'exception').length).toBe(1);
expect(manifest.items.filter(item => item.loader === 'exception-filter').length).toBe(1);
expect(manifest.items.filter(item => item.loader === 'lifecycle-hook-unit').length).toBe(2);
expect(manifest.items.filter(item => item.loader === 'config').length).toBe(1);
expect(manifest.items.filter(item => item.loader === 'module').length).toBe(4);

expect(manifest.items.filter(item => item.unitName === 'redis').length).toBe(2);
expect(manifest.items.filter(item => item.unitName === 'mysql').length).toBe(0);
expect(manifest.items.filter(item => item.source === 'app').length).toBe(8);
expect(manifest.items.filter(item => item.source === 'app').length).toBe(9);
expect(manifest.pluginConfig).toStrictEqual({
redis: { enable: true, path: path.join('src', 'redis_plugin') },
mysql: { enable: false, path: path.join('src', 'mysql_plugin') },
Expand All @@ -37,7 +38,7 @@ describe('test/scanner.test.ts', () => {
// console.log('devManifest', devManifest);
expect(devManifest).toBeDefined();
expect(devManifest.items).toBeDefined();
expect(devManifest.items.length).toBe(12);
expect(devManifest.items.length).toBe(13);
expect(devManifest.items.filter(item => item.loader === 'config').length).toBe(2);
expect(devManifest.items.filter(item => item.loader === 'plugin-meta').length).toBe(2);
expect(devManifest.items.find(item => item.unitName === 'testDuplicate')).toBeDefined();
Expand Down

0 comments on commit 1402d8a

Please sign in to comment.