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 defaults;
let emptyTransformOptions;
let UnableToResolveError;
async function getOrderedDependenciesAsJSON(
dgraphPromise,
@ -95,6 +96,9 @@ describe('traverseDependencies', function() {
Module = require('../../node-haste/Module');
traverseDependencies = require('../traverseDependencies');
({
UnableToResolveError,
} = require('../../node-haste/DependencyGraph/ModuleResolution'));
emptyTransformOptions = {transformer: {transform: {}}};
defaults = {
@ -1024,7 +1028,11 @@ describe('traverseDependencies', function() {
await getOrderedDependenciesAsJSON(dgraph, '/root/index.js');
throw new Error('should be unreachable');
} 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');
throw new Error('should be unreachable');
} 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']
.replace('require("dontWork")', '')
@ -3394,6 +3406,8 @@ describe('traverseDependencies', function() {
describe('node_modules (win32)', function() {
let DependencyGraph;
let processDgraph;
let UnableToResolveError;
beforeEach(() => {
Object.defineProperty(process, 'platform', {
configurable: true,
@ -3406,6 +3420,9 @@ describe('traverseDependencies', function() {
jest.mock('path', () => require.requireActual('path').win32);
DependencyGraph = require('../../node-haste/DependencyGraph');
processDgraph = processDgraphFor.bind(null, DependencyGraph);
({
UnableToResolveError,
} = require('../../node-haste/DependencyGraph/ModuleResolution'));
});
it('should work with nested node_modules', async () => {
@ -3879,7 +3896,11 @@ describe('traverseDependencies', function() {
await getOrderedDependenciesAsJSON(dgraph, entryPath);
throw new Error('should be unreachable');
} 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']
.replace('require("dontWork")', '')
@ -4381,7 +4402,6 @@ describe('traverseDependencies', function() {
});
it('updates module dependencies on file delete', async () => {
expect.assertions(1);
var root = '/root';
var filesystem = setMockFileSystem({
root: {
@ -4418,7 +4438,11 @@ describe('traverseDependencies', function() {
await getOrderedDependenciesAsJSON(dgraph, '/root/index.js');
throw new Error('should be unreachable');
} 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);
throw new Error('should be unreachable');
} 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'] = '';
await triggerAndProcessWatchEvent(dgraph, 'change', root + '/foo.png');
@ -5006,7 +5034,11 @@ describe('traverseDependencies', function() {
await getOrderedDependenciesAsJSON(dgraph, '/root/index.jsx');
throw Error('should be unreachable');
} 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';
const {
UnableToResolveError,
} = require('../node-haste/DependencyGraph/ModuleResolution');
const {
AmbiguousModuleResolutionError,
} = require('../node-haste/DependencyGraph/ResolutionRequest');
@ -52,10 +55,9 @@ function formatBundlingError(
}
if (
error instanceof Error &&
(error.type === 'TransformError' ||
error.type === 'NotFoundError' ||
error.type === 'UnableToResolveError')
error instanceof UnableToResolveError ||
(error instanceof Error &&
(error.type === 'TransformError' || error.type === 'NotFoundError'))
) {
error.errors = [
{

View File

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