Skip to content

Commit 8934ec9

Browse files
committed
Propagate original error messages to require calls, Closes #65
1 parent 0d97782 commit 8934ec9

File tree

7 files changed

+54
-29
lines changed

7 files changed

+54
-29
lines changed

lib/construction/strategy/ConstructionStrategyCommonJs.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ export class ConstructionStrategyCommonJs implements IConstructionStrategy<any>
2525
public createInstance(options: ICreationStrategyInstanceOptions<any>): any {
2626
// Call require()
2727
options.requireName = this.overrideRequireNames[options.requireName] || options.requireName;
28+
29+
// First try requiring current module, and fallback to a plain require
2830
let object: any;
29-
try {
30-
object = this.requireCurrentRunningModuleIfCurrent(options.moduleState, options.requireName);
31-
} catch {
32-
// Always require relative from main module, because Components.js will in most cases just be dependency.
33-
object = this.req(options.requireName.startsWith('.') ?
31+
const currentResult = this.requireCurrentRunningModuleIfCurrent(options.moduleState, options.requireName);
32+
object = currentResult !== false ?
33+
currentResult.value :
34+
this.req(options.requireName.startsWith('.') ?
3435
Path.join(process.cwd(), options.requireName) :
3536
this.req.resolve(options.requireName, { paths: [ options.moduleState.mainModulePath ]}));
36-
}
3737

3838
// Determine the child of the require'd element
3939
let subObject;
@@ -70,18 +70,18 @@ export class ConstructionStrategyCommonJs implements IConstructionStrategy<any>
7070
* @param requireName The module name that should be required.
7171
* @returns {any} The require() result
7272
*/
73-
public requireCurrentRunningModuleIfCurrent(moduleState: IModuleState, requireName: string): void {
73+
public requireCurrentRunningModuleIfCurrent(moduleState: IModuleState, requireName: string): { value: any } | false {
7474
const pckg = moduleState.packageJsons[moduleState.mainModulePath];
7575
if (pckg) {
7676
if (requireName === pckg.name) {
7777
const mainPath: string = Path.posix.join(moduleState.mainModulePath, pckg.main);
7878
const required = this.req(mainPath);
7979
if (required) {
80-
return required;
80+
return { value: required };
8181
}
8282
}
8383
}
84-
throw new Error('Component is not the main module');
84+
return false;
8585
}
8686

8787
public createHash(options: ICreationStrategyHashOptions<any>): any {

lib/construction/strategy/ConstructionStrategyCommonJsString.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,16 @@ export class ConstructionStrategyCommonJsString implements IConstructionStrategy
4444
public createInstance(options: ICreationStrategyInstanceOptions<string>): string {
4545
// Call require()
4646
options.requireName = this.overrideRequireNames[options.requireName] || options.requireName;
47-
let resultingRequirePath: string;
48-
try {
49-
this.strategyCommonJs.requireCurrentRunningModuleIfCurrent(options.moduleState, options.requireName);
50-
resultingRequirePath = `.${Path.sep}${Path.relative(options.moduleState.mainModulePath,
51-
this.getCurrentRunningModuleMain(options.moduleState))}`;
52-
} catch {
53-
resultingRequirePath = options.requireName;
54-
}
47+
48+
// First try requiring current module, and fallback to a plain require
49+
const currentResult = this.strategyCommonJs
50+
.requireCurrentRunningModuleIfCurrent(options.moduleState, options.requireName);
51+
const resultingRequirePath = currentResult !== false ?
52+
`.${Path.sep}${Path.relative(
53+
options.moduleState.mainModulePath,
54+
this.getCurrentRunningModuleMain(options.moduleState),
55+
)}` :
56+
options.requireName;
5557
let serialization = `require('${resultingRequirePath.replace(/\\/gu, '/')}')`;
5658

5759
// Determine the child of the require'd element

test/integration/instantiateFile-test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ describe('construction with component configs as files', () => {
1818
importPaths: {
1919
'http://example.org/': `${__dirname}/../`,
2020
},
21+
packageJsons: {},
2122
};
2223
jest.clearAllMocks();
2324
});

test/integration/instantiateResourceConfigComponent-test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ describe('construction with component configs as Resource', () => {
2222
mainModulePath: `${__dirname}/../../__mocks__`,
2323
moduleState: <any> {
2424
mainModulePath: `${__dirname}/../../__mocks__`,
25+
packageJsons: {},
2526
},
2627
async moduleLoader() {
2728
// Register nothing

test/integration/instantiateResourceConfigComponentMapped-test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ describe('construction with mapped component configs as Resource', () => {
2424
mainModulePath: `${__dirname}/../../__mocks__`,
2525
moduleState: <any> {
2626
mainModulePath: `${__dirname}/../../__mocks__`,
27+
packageJsons: {},
2728
},
2829
async moduleLoader() {
2930
// Register nothing

test/integration/instantiateResourceConfigRaw-test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ describe('construction with component configs as Resource', () => {
2222
mainModulePath: `${__dirname}/../../__mocks__`,
2323
moduleState: <any> {
2424
mainModulePath: `${__dirname}/../../__mocks__`,
25+
packageJsons: {},
2526
},
2627
async moduleLoader() {
2728
// Register nothing

test/unit/construction/strategy/ConstructionStrategyCommonJs-test.ts

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -267,15 +267,15 @@ describe('ConstructionStrategyCommonJs', () => {
267267
describe('requireCurrentRunningModuleIfCurrent', () => {
268268
it('for the current module should require its main entry', () => {
269269
expect(constructionStrategy.requireCurrentRunningModuleIfCurrent(moduleState, 'currentmodule'))
270-
.toBe(requireMain);
270+
.toEqual({ value: requireMain });
271271
});
272272

273-
it('for an unknown package should throw', () => {
274-
expect(() => constructionStrategy.requireCurrentRunningModuleIfCurrent(moduleState, 'unknownmodule'))
275-
.toThrow(new Error('Component is not the main module'));
273+
it('for an unknown package should return false', () => {
274+
expect(constructionStrategy.requireCurrentRunningModuleIfCurrent(moduleState, 'unknownmodule'))
275+
.toBe(false);
276276
});
277277

278-
it('for a main module path pointing to unknown package should throw', () => {
278+
it('for a main module path pointing to unknown package should return false', () => {
279279
moduleState = {
280280
componentModules: {},
281281
contexts: {},
@@ -290,11 +290,11 @@ describe('ConstructionStrategyCommonJs', () => {
290290
},
291291
},
292292
};
293-
expect(() => constructionStrategy.requireCurrentRunningModuleIfCurrent(moduleState, 'currentmodule'))
294-
.toThrow(new Error('Component is not the main module'));
293+
expect(constructionStrategy.requireCurrentRunningModuleIfCurrent(moduleState, 'currentmodule'))
294+
.toBe(false);
295295
});
296296

297-
it('for a different package should throw', () => {
297+
it('for a different package should return false', () => {
298298
moduleState = {
299299
componentModules: {},
300300
contexts: {},
@@ -309,11 +309,11 @@ describe('ConstructionStrategyCommonJs', () => {
309309
},
310310
},
311311
};
312-
expect(() => constructionStrategy.requireCurrentRunningModuleIfCurrent(moduleState, 'currentmodule'))
313-
.toThrow(new Error('Component is not the main module'));
312+
expect(constructionStrategy.requireCurrentRunningModuleIfCurrent(moduleState, 'currentmodule'))
313+
.toBe(false);
314314
});
315315

316-
it('for an invalid main should throw', () => {
316+
it('for an empty main should return false', () => {
317317
moduleState = {
318318
componentModules: {},
319319
contexts: {},
@@ -328,8 +328,27 @@ describe('ConstructionStrategyCommonJs', () => {
328328
},
329329
},
330330
};
331+
expect(constructionStrategy.requireCurrentRunningModuleIfCurrent(moduleState, 'currentmodule'))
332+
.toBe(false);
333+
});
334+
335+
it('for an invalid main should throw', () => {
336+
moduleState = {
337+
componentModules: {},
338+
contexts: {},
339+
importPaths: {},
340+
mainModulePath: 'mainmodulepath',
341+
nodeModuleImportPaths: [],
342+
nodeModulePaths: [],
343+
packageJsons: {
344+
mainmodulepath: {
345+
name: 'currentmodule',
346+
main: 'INVALID',
347+
},
348+
},
349+
};
331350
expect(() => constructionStrategy.requireCurrentRunningModuleIfCurrent(moduleState, 'currentmodule'))
332-
.toThrow(new Error('Component is not the main module'));
351+
.toThrow(new Error('Invalid require'));
333352
});
334353
});
335354

0 commit comments

Comments
 (0)