metro: cleanup UnableToResolveError

Summary: I want to get rid of `TModule` and stuff so that we can eventually reunite this with `jest-resolve`. This is a continuation of the cleanup I started a long time ago.

Reviewed By: davidaurelio

Differential Revision: D6601657

fbshipit-source-id: 62c1806783323ee50e9a09146c73006c721eb891
This commit is contained in:
Jean Lauliac 2017-12-20 01:48:14 -08:00 committed by Facebook Github Bot
parent 056ea9b5bf
commit c9023fd907
3 changed files with 70 additions and 27 deletions

View File

@ -52,6 +52,7 @@ describe('traverseDependencies', function() {
let traverseDependencies; let traverseDependencies;
let defaults; let defaults;
let emptyTransformOptions; let emptyTransformOptions;
let UnableToResolveError;
async function getOrderedDependenciesAsJSON( async function getOrderedDependenciesAsJSON(
dgraphPromise, dgraphPromise,
@ -95,6 +96,9 @@ describe('traverseDependencies', function() {
Module = require('../../node-haste/Module'); Module = require('../../node-haste/Module');
traverseDependencies = require('../traverseDependencies'); traverseDependencies = require('../traverseDependencies');
({
UnableToResolveError,
} = require('../../node-haste/DependencyGraph/ModuleResolution'));
emptyTransformOptions = {transformer: {transform: {}}}; emptyTransformOptions = {transformer: {transform: {}}};
defaults = { defaults = {
@ -1024,7 +1028,11 @@ describe('traverseDependencies', function() {
await getOrderedDependenciesAsJSON(dgraph, '/root/index.js'); await getOrderedDependenciesAsJSON(dgraph, '/root/index.js');
throw new Error('should be unreachable'); throw new Error('should be unreachable');
} catch (error) { } catch (error) {
expect(error.type).toEqual('UnableToResolveError'); if (!(error instanceof UnableToResolveError)) {
throw error;
}
expect(error.originModulePath).toBe('/root/index.js');
expect(error.targetModuleName).toBe('lolomg');
} }
}); });
}); });
@ -2972,7 +2980,11 @@ describe('traverseDependencies', function() {
await getOrderedDependenciesAsJSON(dgraph, '/root/index.js'); await getOrderedDependenciesAsJSON(dgraph, '/root/index.js');
throw new Error('should be unreachable'); throw new Error('should be unreachable');
} catch (error) { } catch (error) {
expect(error.type).toEqual('UnableToResolveError'); if (!(error instanceof UnableToResolveError)) {
throw error;
}
expect(error.originModulePath).toBe('/root/index.js');
expect(error.targetModuleName).toBe('dontWork');
} }
filesystem.root['index.js'] = filesystem.root['index.js'] filesystem.root['index.js'] = filesystem.root['index.js']
.replace('require("dontWork")', '') .replace('require("dontWork")', '')
@ -3394,6 +3406,8 @@ describe('traverseDependencies', function() {
describe('node_modules (win32)', function() { describe('node_modules (win32)', function() {
let DependencyGraph; let DependencyGraph;
let processDgraph; let processDgraph;
let UnableToResolveError;
beforeEach(() => { beforeEach(() => {
Object.defineProperty(process, 'platform', { Object.defineProperty(process, 'platform', {
configurable: true, configurable: true,
@ -3406,6 +3420,9 @@ describe('traverseDependencies', function() {
jest.mock('path', () => require.requireActual('path').win32); jest.mock('path', () => require.requireActual('path').win32);
DependencyGraph = require('../../node-haste/DependencyGraph'); DependencyGraph = require('../../node-haste/DependencyGraph');
processDgraph = processDgraphFor.bind(null, DependencyGraph); processDgraph = processDgraphFor.bind(null, DependencyGraph);
({
UnableToResolveError,
} = require('../../node-haste/DependencyGraph/ModuleResolution'));
}); });
it('should work with nested node_modules', async () => { it('should work with nested node_modules', async () => {
@ -3879,7 +3896,11 @@ describe('traverseDependencies', function() {
await getOrderedDependenciesAsJSON(dgraph, entryPath); await getOrderedDependenciesAsJSON(dgraph, entryPath);
throw new Error('should be unreachable'); throw new Error('should be unreachable');
} catch (error) { } catch (error) {
expect(error.type).toEqual('UnableToResolveError'); if (!(error instanceof UnableToResolveError)) {
throw error;
}
expect(error.originModulePath).toBe('C:\\root\\index.js');
expect(error.targetModuleName).toBe('dontWork');
} }
filesystem.root['index.js'] = filesystem.root['index.js'] filesystem.root['index.js'] = filesystem.root['index.js']
.replace('require("dontWork")', '') .replace('require("dontWork")', '')
@ -4381,7 +4402,6 @@ describe('traverseDependencies', function() {
}); });
it('updates module dependencies on file delete', async () => { it('updates module dependencies on file delete', async () => {
expect.assertions(1);
var root = '/root'; var root = '/root';
var filesystem = setMockFileSystem({ var filesystem = setMockFileSystem({
root: { root: {
@ -4418,7 +4438,11 @@ describe('traverseDependencies', function() {
await getOrderedDependenciesAsJSON(dgraph, '/root/index.js'); await getOrderedDependenciesAsJSON(dgraph, '/root/index.js');
throw new Error('should be unreachable'); throw new Error('should be unreachable');
} catch (error) { } catch (error) {
expect(error.type).toEqual('UnableToResolveError'); if (!(error instanceof UnableToResolveError)) {
throw error;
}
expect(error.originModulePath).toBe('/root/index.js');
expect(error.targetModuleName).toBe('foo');
} }
}); });
}); });
@ -4527,7 +4551,11 @@ describe('traverseDependencies', function() {
await getOrderedDependenciesAsJSON(dgraph, entryPath); await getOrderedDependenciesAsJSON(dgraph, entryPath);
throw new Error('should be unreachable'); throw new Error('should be unreachable');
} catch (error) { } catch (error) {
expect(error.type).toEqual('UnableToResolveError'); if (!(error instanceof UnableToResolveError)) {
throw error;
}
expect(error.originModulePath).toBe('/root/index.js');
expect(error.targetModuleName).toBe('./foo.png');
} }
filesystem.root['foo.png'] = ''; filesystem.root['foo.png'] = '';
await triggerAndProcessWatchEvent(dgraph, 'change', root + '/foo.png'); await triggerAndProcessWatchEvent(dgraph, 'change', root + '/foo.png');
@ -5006,7 +5034,11 @@ describe('traverseDependencies', function() {
await getOrderedDependenciesAsJSON(dgraph, '/root/index.jsx'); await getOrderedDependenciesAsJSON(dgraph, '/root/index.jsx');
throw Error('should be unreachable'); throw Error('should be unreachable');
} catch (error) { } catch (error) {
expect(error.type).toEqual('UnableToResolveError'); if (!(error instanceof UnableToResolveError)) {
throw error;
}
expect(error.originModulePath).toBe('/root/index.jsx');
expect(error.targetModuleName).toBe('./a');
} }
}); });
}); });

View File

@ -12,6 +12,9 @@
'use strict'; 'use strict';
const {
UnableToResolveError,
} = require('../node-haste/DependencyGraph/ModuleResolution');
const { const {
AmbiguousModuleResolutionError, AmbiguousModuleResolutionError,
} = require('../node-haste/DependencyGraph/ResolutionRequest'); } = require('../node-haste/DependencyGraph/ResolutionRequest');
@ -52,10 +55,9 @@ function formatBundlingError(
} }
if ( if (
error instanceof Error && error instanceof UnableToResolveError ||
(error.type === 'TransformError' || (error instanceof Error &&
error.type === 'NotFoundError' || (error.type === 'TransformError' || error.type === 'NotFoundError'))
error.type === 'UnableToResolveError')
) { ) {
error.errors = [ error.errors = [
{ {

View File

@ -112,7 +112,7 @@ function tryResolveSync<T>(action: () => T, secondaryAction: () => T): T {
try { try {
return action(); return action();
} catch (error) { } catch (error) {
if (error.type !== 'UnableToResolveError') { if (!(error instanceof UnableToResolveError)) {
throw error; throw error;
} }
return secondaryAction(); return secondaryAction();
@ -189,7 +189,7 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
} }
throw new UnableToResolveError( throw new UnableToResolveError(
fromModule, fromModule.path,
toModuleName, toModuleName,
'Unable to resolve dependency', 'Unable to resolve dependency',
); );
@ -290,7 +290,7 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
const hint = displaySearchQueue.length ? ' or in these directories:' : ''; const hint = displaySearchQueue.length ? ' or in these directories:' : '';
throw new UnableToResolveError( throw new UnableToResolveError(
fromModule, fromModule.path,
toModuleName, toModuleName,
`Module does not exist in the module map${hint}\n` + `Module does not exist in the module map${hint}\n` +
displaySearchQueue displaySearchQueue
@ -328,7 +328,7 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
const {dir} = result.candidates; const {dir} = result.candidates;
if (dir.type === 'package') { if (dir.type === 'package') {
throw new UnableToResolveError( throw new UnableToResolveError(
fromModule, fromModule.path,
toModuleName, toModuleName,
`could not resolve \`${potentialModulePath}' as a folder: it ` + `could not resolve \`${potentialModulePath}' as a folder: it ` +
'contained a package, but its "main" could not be resolved', 'contained a package, but its "main" could not be resolved',
@ -336,7 +336,7 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
} }
invariant(dir.type === 'index', 'invalid candidate type'); invariant(dir.type === 'index', 'invalid candidate type');
throw new UnableToResolveError( throw new UnableToResolveError(
fromModule, fromModule.path,
toModuleName, toModuleName,
`could not resolve \`${potentialModulePath}' as a file nor as a folder`, `could not resolve \`${potentialModulePath}' as a file nor as a folder`,
); );
@ -472,7 +472,7 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
return module; return module;
} }
throw new UnableToResolveError( throw new UnableToResolveError(
fromModule, fromModule.path,
toModuleName, toModuleName,
"could not resolve `${ModuleResolver.EMPTY_MODULE}'", "could not resolve `${ModuleResolver.EMPTY_MODULE}'",
); );
@ -583,22 +583,31 @@ function failedFor<TModule, TCandidates>(
return {type: 'failed', candidates}; return {type: 'failed', candidates};
} }
class UnableToResolveError<TModule: Moduleish> extends Error { class UnableToResolveError extends Error {
type: string; /**
from: string; * File path of the module that tried to require a module, ex. `/js/foo.js`.
to: string; */
originModulePath: string;
/**
* The name of the module that was required, no necessarily a path,
* ex. `./bar`, or `invariant`.
*/
targetModuleName: string;
constructor(fromModule: TModule, toModule: string, message: string) { constructor(
originModulePath: string,
targetModuleName: string,
message: string,
) {
super(); super();
this.from = fromModule.path; this.originModulePath = originModulePath;
this.to = toModule; this.targetModuleName = targetModuleName;
this.message = util.format( this.message = util.format(
'Unable to resolve module `%s` from `%s`: %s', 'Unable to resolve module `%s` from `%s`: %s',
toModule, targetModuleName,
fromModule.path, originModulePath,
message, message,
); );
this.type = this.name = 'UnableToResolveError';
} }
} }