Better NotFound error handling in CodeFetch

throwResolutionError was swallowing unrelated errors.
This commit is contained in:
Ryan Dahl 2018-09-08 16:40:16 -04:00
parent 8090fb252b
commit e2a285b871
4 changed files with 42 additions and 54 deletions

View file

@ -117,20 +117,6 @@ export class ModuleMetaData implements ts.IScriptSnapshot {
} }
} }
/**
* Throw a module resolution error, when a module is unsuccessfully resolved.
*/
function throwResolutionError(
message: string,
moduleSpecifier: ModuleSpecifier,
containingFile: ContainingFile
): never {
throw new Error(
// tslint:disable-next-line:max-line-length
`Cannot resolve module "${moduleSpecifier}" from "${containingFile}".\n ${message}`
);
}
/** /**
* A singleton class that combines the TypeScript Language Service host API * A singleton class that combines the TypeScript Language Service host API
* with Deno specific APIs to provide an interface for compiling and running * with Deno specific APIs to provide an interface for compiling and running
@ -514,9 +500,9 @@ export class DenoCompiler
if (fileName && this._moduleMetaDataMap.has(fileName)) { if (fileName && this._moduleMetaDataMap.has(fileName)) {
return this._moduleMetaDataMap.get(fileName)!; return this._moduleMetaDataMap.get(fileName)!;
} }
let moduleId: ModuleId = ""; let moduleId: ModuleId;
let sourceCode: SourceCode | undefined; let sourceCode: SourceCode;
let outputCode: OutputCode | undefined; let outputCode: OutputCode | null;
if ( if (
moduleSpecifier.startsWith(ASSETS) || moduleSpecifier.startsWith(ASSETS) ||
containingFile.startsWith(ASSETS) containingFile.startsWith(ASSETS)
@ -524,38 +510,24 @@ export class DenoCompiler
// Assets are compiled into the runtime javascript bundle. // Assets are compiled into the runtime javascript bundle.
// we _know_ `.pop()` will return a string, but TypeScript doesn't so // we _know_ `.pop()` will return a string, but TypeScript doesn't so
// not null assertion // not null assertion
const moduleId = moduleSpecifier.split("/").pop()!; moduleId = moduleSpecifier.split("/").pop()!;
const assetName = moduleId.includes(".") ? moduleId : `${moduleId}.d.ts`; const assetName = moduleId.includes(".") ? moduleId : `${moduleId}.d.ts`;
assert(assetName in assetSourceCode, `No such asset "${assetName}"`); assert(assetName in assetSourceCode, `No such asset "${assetName}"`);
sourceCode = assetSourceCode[assetName]; sourceCode = assetSourceCode[assetName];
fileName = `${ASSETS}/${assetName}`; fileName = `${ASSETS}/${assetName}`;
outputCode = "";
} else { } else {
// We query Rust with a CodeFetch message. It will load the sourceCode, // We query Rust with a CodeFetch message. It will load the sourceCode,
// and if there is any outputCode cached, will return that as well. // and if there is any outputCode cached, will return that as well.
let fetchResponse; const fetchResponse = this._os.codeFetch(moduleSpecifier, containingFile);
try { moduleId = fetchResponse.moduleName!;
fetchResponse = this._os.codeFetch(moduleSpecifier, containingFile); fileName = fetchResponse.filename!;
} catch (e) { sourceCode = fetchResponse.sourceCode!;
return throwResolutionError( outputCode = fetchResponse.outputCode!;
`os.codeFetch message: ${e.message}`,
moduleSpecifier,
containingFile
);
}
moduleId = fetchResponse.moduleName || "";
fileName = fetchResponse.filename || undefined;
sourceCode = fetchResponse.sourceCode || undefined;
outputCode = fetchResponse.outputCode || undefined;
}
if (!sourceCode || sourceCode.length === 0 || !fileName) {
return throwResolutionError(
"Invalid source code or file name.",
moduleSpecifier,
containingFile
);
} }
assert(sourceCode!.length > 0);
this._log("resolveModule sourceCode length:", sourceCode.length); this._log("resolveModule sourceCode length:", sourceCode.length);
this._log("resolveModule has outputCode:", !!outputCode); this._log("resolveModule has outputCode:", outputCode! != null);
this._setFileName(moduleSpecifier, containingFile, fileName); this._setFileName(moduleSpecifier, containingFile, fileName);
if (fileName && this._moduleMetaDataMap.has(fileName)) { if (fileName && this._moduleMetaDataMap.has(fileName)) {
return this._moduleMetaDataMap.get(fileName)!; return this._moduleMetaDataMap.get(fileName)!;

View file

@ -1,6 +1,7 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license. // Copyright 2018 the Deno authors. All rights reserved. MIT license.
use errors::DenoError; use errors::DenoError;
use errors::DenoResult; use errors::DenoResult;
use errors::ErrorKind;
use fs as deno_fs; use fs as deno_fs;
use net; use net;
use ring; use ring;
@ -159,7 +160,7 @@ impl DenoDir {
let (module_name, filename) = let (module_name, filename) =
self.resolve_module(module_specifier, containing_file)?; self.resolve_module(module_specifier, containing_file)?;
let out = self let result = self
.get_source_code(module_name.as_str(), filename.as_str()) .get_source_code(module_name.as_str(), filename.as_str())
.and_then(|source_code| { .and_then(|source_code| {
Ok(CodeFetchOutput { Ok(CodeFetchOutput {
@ -168,7 +169,24 @@ impl DenoDir {
source_code, source_code,
maybe_output_code: None, maybe_output_code: None,
}) })
})?; });
let out = match result {
Err(err) => {
if err.kind() == ErrorKind::NotFound {
// For NotFound, change the message to something better.
return Err(DenoError::from(std::io::Error::new(
std::io::ErrorKind::NotFound,
format!(
"Cannot resolve module \"{}\" from \"{}\"",
module_specifier, containing_file
),
)));
} else {
return Err(err);
}
}
Ok(out) => out,
};
let result = let result =
self.load_cache(out.filename.as_str(), out.source_code.as_str()); self.load_cache(out.filename.as_str(), out.source_code.as_str());

View file

@ -1,12 +1,11 @@
Error: Cannot resolve module "bad-module.ts" from "[WILDCARD]error_004_missing_module.ts". NotFound: Cannot resolve module "bad-module.ts" from "[WILDCARD]/tests/error_004_missing_module.ts"
os.codeFetch message: [WILDCARD] (os error 2) at maybeError (deno/js/errors.ts:[WILDCARD])
at throwResolutionError (deno/js/compiler.ts:[WILDCARD]) at maybeThrowError (deno/js/errors.ts:[WILDCARD])
at send (deno/js/fbs_util.ts:[WILDCARD])
at Object.codeFetch (deno/js/os.ts:[WILDCARD])
at DenoCompiler.resolveModule (deno/js/compiler.ts:[WILDCARD]) at DenoCompiler.resolveModule (deno/js/compiler.ts:[WILDCARD])
at DenoCompiler._resolveModuleName (deno/js/compiler.ts:[WILDCARD]) at DenoCompiler._resolveModuleName (deno/js/compiler.ts:[WILDCARD])
at moduleNames.map.name (deno/js/compiler.ts:[WILDCARD]) at moduleNames.map.name (deno/js/compiler.ts:[WILDCARD])
at Array.map (<anonymous>) at Array.map (<anonymous>)
at DenoCompiler.resolveModuleNames (deno/js/compiler.ts:[WILDCARD]) at DenoCompiler.resolveModuleNames (deno/js/compiler.ts:[WILDCARD])
at Object.compilerHost.resolveModuleNames (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD]) at Object.compilerHost.resolveModuleNames (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD])
at resolveModuleNamesWorker (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD])
at resolveModuleNamesReusingOldState (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD])
at processImportedModules (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD])

View file

@ -1,12 +1,11 @@
Error: Cannot resolve module "bad-module.ts" from "[WILDCARD]deno/tests/error_005_missing_dynamic_import.ts". NotFound: Cannot resolve module "bad-module.ts" from "[WILDCARD]deno/tests/error_005_missing_dynamic_import.ts"
os.codeFetch message: [WILDCARD] (os error 2) at maybeError (deno/js/errors.ts:[WILDCARD])
at throwResolutionError (deno/js/compiler.ts:[WILDCARD]) at maybeThrowError (deno/js/errors.ts:[WILDCARD])
at send (deno/js/fbs_util.ts:[WILDCARD])
at Object.codeFetch (deno/js/os.ts:[WILDCARD])
at DenoCompiler.resolveModule (deno/js/compiler.ts:[WILDCARD]) at DenoCompiler.resolveModule (deno/js/compiler.ts:[WILDCARD])
at DenoCompiler._resolveModuleName (deno/js/compiler.ts:[WILDCARD]) at DenoCompiler._resolveModuleName (deno/js/compiler.ts:[WILDCARD])
at moduleNames.map.name (deno/js/compiler.ts:[WILDCARD]) at moduleNames.map.name (deno/js/compiler.ts:[WILDCARD])
at Array.map (<anonymous>) at Array.map (<anonymous>)
at DenoCompiler.resolveModuleNames (deno/js/compiler.ts:[WILDCARD]) at DenoCompiler.resolveModuleNames (deno/js/compiler.ts:[WILDCARD])
at Object.compilerHost.resolveModuleNames (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD]) at Object.compilerHost.resolveModuleNames (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD])
at resolveModuleNamesWorker (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD])
at resolveModuleNamesReusingOldState (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD])
at processImportedModules (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD])