Skip to content

Commit

Permalink
fix(core): invalid scopes on module re-export #2341
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilmysliwiec committed Jun 5, 2019
1 parent 1167450 commit f210ebc
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 23 deletions.
21 changes: 14 additions & 7 deletions packages/core/errors/exceptions-zone.ts
@@ -1,24 +1,31 @@
import { ExceptionHandler } from './exception-handler';
import { UNHANDLED_RUNTIME_EXCEPTION } from './messages';

const DEFAULT_TEARDOWN = () => process.exit(1);

export class ExceptionsZone {
private static readonly exceptionHandler = new ExceptionHandler();

public static run(fn: () => void) {
public static run(
callback: () => void,
teardown: (err: any) => void = DEFAULT_TEARDOWN,
) {
try {
fn();
callback();
} catch (e) {
this.exceptionHandler.handle(e);
throw UNHANDLED_RUNTIME_EXCEPTION;
teardown(e);
}
}

public static async asyncRun(fn: () => Promise<void>) {
public static async asyncRun(
callback: () => Promise<void>,
teardown: (err: any) => void = DEFAULT_TEARDOWN,
) {
try {
await fn();
await callback();
} catch (e) {
this.exceptionHandler.handle(e);
throw UNHANDLED_RUNTIME_EXCEPTION;
teardown(e);
}
}
}
11 changes: 10 additions & 1 deletion packages/core/injector/injector.ts
Expand Up @@ -444,12 +444,20 @@ export class Injector {
moduleRegistry: any[] = [],
contextId = STATIC_CONTEXT,
inquirer?: InstanceWrapper,
isTraversing?: boolean,
): Promise<any> {
let instanceWrapperRef: InstanceWrapper = null;

const imports = module.imports || new Set<Module>();
const children = [...imports.values()].filter(item => item);
const identity = (item: any) => item;

let children = [...imports.values()].filter(identity);
if (isTraversing) {
const contextModuleExports = module.exports;
children = children.filter(child =>
contextModuleExports.has(child.metatype && child.metatype.name),
);
}
for (const relatedModule of children) {
if (moduleRegistry.includes(relatedModule.id)) {
continue;
Expand All @@ -464,6 +472,7 @@ export class Injector {
moduleRegistry,
contextId,
inquirer,
true,
);
if (instanceRef) {
return instanceRef;
Expand Down
31 changes: 16 additions & 15 deletions packages/core/test/errors/test/exceptions-zone.spec.ts
@@ -1,34 +1,35 @@
import * as sinon from 'sinon';
import { expect } from 'chai';
import * as sinon from 'sinon';
import { ExceptionsZone } from '../../../errors/exceptions-zone';
import { UNHANDLED_RUNTIME_EXCEPTION } from '../../../errors/messages';

describe('ExceptionsZone', () => {
const rethrow = err => {
throw err;
};

describe('run', () => {
let callback: sinon.SinonSpy;
beforeEach(() => {
callback = sinon.spy();
});
it('should call callback', () => {
ExceptionsZone.run(callback as any);
ExceptionsZone.run(callback as any, rethrow);
expect(callback.called).to.be.true;
});
describe('when callback throws exception', () => {
const exceptionHandler = {
handle: () => {},
};
let handleSpy: sinon.SinonSpy;
beforeEach(() => {
before(() => {
(ExceptionsZone as any).exceptionHandler = exceptionHandler;
handleSpy = sinon.spy(exceptionHandler, 'handle');
});
it('should call "handle" method of exceptionHandler and throws UNHANDLED_RUNTIME_EXCEPTION', () => {
it('should call "handle" method of exceptionHandler and rethrows', () => {
const throwsCallback = () => {
throw 3;
throw new Error('');
};
expect(() => ExceptionsZone.run(throwsCallback)).to.throws(
UNHANDLED_RUNTIME_EXCEPTION,
);
expect(() => ExceptionsZone.run(throwsCallback, rethrow)).to.throws();
expect(handleSpy.called).to.be.true;
});
});
Expand All @@ -39,24 +40,24 @@ describe('ExceptionsZone', () => {
callback = sinon.spy();
});
it('should call callback', async () => {
await ExceptionsZone.asyncRun(callback as any);
await ExceptionsZone.asyncRun(callback as any, rethrow);
expect(callback.called).to.be.true;
});
describe('when callback throws exception', () => {
const exceptionHandler = {
handle: () => {},
};
let handleSpy: sinon.SinonSpy;
beforeEach(() => {
before(() => {
(ExceptionsZone as any).exceptionHandler = exceptionHandler;
handleSpy = sinon.spy(exceptionHandler, 'handle');
});
it('should call "handle" method of exceptionHandler and throws UNHANDLED_RUNTIME_EXCEPTION', async () => {
it('should call "handle" method of exceptionHandler and rethrows error', async () => {
const throwsCallback = () => {
throw 3;
throw new Error('');
};
expect(ExceptionsZone.asyncRun(throwsCallback)).to.eventually.be
.rejected;
expect(ExceptionsZone.asyncRun(throwsCallback, rethrow)).to.eventually
.be.rejected;
});
});
});
Expand Down

0 comments on commit f210ebc

Please sign in to comment.