Importing modules that don't exist
It should throw a static error, the loader is where this is specified I believe, but it looks like the loader was pulled out into it's own spec rwaldron/tc39-notes/blob/b1af70ec299e996a9f1e2e34746269fbbb835d7e/es6/2014-09/sept-25.md#loader-pipeline, not sure where that ended up living.
On Nov 13, 2014, at 5:16 AM, Calvin Metcalf wrote:
It should throw a static error, the loader is where this is specified I believe, but it looks like the loader was pulled out into it's own spec rwaldron/tc39-notes/blob/b1af70ec299e996a9f1e2e34746269fbbb835d7e/es6/2014-09/sept-25.md#loader-pipeline, not sure where that ended up living.
On Thu, Nov 13, 2014 at 7:37 AM, Isiah Meadows <impinball at gmail.com> wrote: What happens if a module isn't able to be found? Is that implementation defined, or have I missed it in the spec?
See people.mozilla.org/~jorendorff/es6-draft.html#sec-stati-semantics-parsemoduleandimports-realm-modulename.-visited steps 10 and 11. If the "host" can not provide the source for a module (as would be the case if the module name is invalid or the module is missing) HostGetSource is supposed to throw an throw an exception. However, the actual exception that is thrown in that case is not currently specified.
For an invalid name in an import declaration, this would occur during a recursive call to ParseModu8leAndImports, stoep 17.d
Should we, then, throw a SyntaxError, a new Error subclass created for the purpose, since we don't have a dedicated Error class for it yet (e.g. ImportError), or just a generic Error?
My thoughts about each option:
- SyntaxError isn't relevant, since it's about a file that doesn't exist, not an actual syntactic problem with the code.
- A new Error subclass can easily be made descriptive, but it would add another variable into the global namespace, and we all know the risks associated with that.
- A generic Error wouldn't tell us anything unless we parse the console output, which is inherently not portable. The only way this will become significant is in System.loader, where failures are probably very important. That could become quickly meaningful on the Web, where scripts are run as ScriptBody, without the module semantics.
Why I suggested throwing a static ReferenceError is because module specifiers are references, specifically references to files. Static errors are almost never caught, since the only place to catch them is in an eval or equivalent.
Looking back, it may be best for implementors to have to figure out what to do with missing modules.
a native ImportError seems to me the best option and it's also easy to polyfill in a meaningful way with all current module loaders used already out there.
just my 2 cents
On Fri, Nov 21, 2014 at 11:49 AM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:
a native ImportError seems to me the best option and it's also easy to polyfill in a meaningful way with all current module loaders used already out there.
My experience with AMD and require.js is that it is very useful for the
error to include not only the module that couldn't be loaded but also the
module that requested it. These two fields should be on the Error object,
and so a new ImportError with the field missingModule
and requestedBy
(or something similar) sounds like a good solution to me.
Marius Gundersen
Traceur reports such errors like this:
// Error: File not found 'feature/Modules/resources/no_such_file.js' // Error: Specified as ./resources/no_such_file.js. // Error: Imported by feature/Modules/Error_InvalidModuleDeclaration.module.js. // Error: Normalizes to feature/Modules/resources/no_such_file.js // Error: locate resolved against base './'
import * as b from './resources/no_such_file.js';
jjb
to be honest I think that .file
and .line
would cover the "who imported
what" scenario but those look like a very good/complete .message
for such
error, nice job
At least using the older loader spec 'file' and 'line' alone is not enough information for the loader to determine which file to load. I think the error message should echo all of the information the developer would need to recreate the error state and hopefully diagnose the issue. I agree that the importing line would be a good addition.
jjb
if we have that and a very descriptive message then we won't need new properties there but still I think having a different kind of instanceof Error is helpful too. It's hard to guess through message parsing otherwise ;-)
On Fri, Nov 21, 2014 at 6:39 PM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:
if we have that and a very descriptive message then we won't need new properties there but still I think having a different kind of instanceof Error is helpful too. It's hard to guess through message parsing otherwise ;-)
As always I believe the properties should be machine readable and therefore be exposed on the Error object instead of having to parse the message.
Marius Gundersen
Easy enough:
class ImportError extends Error {}
Now, patching module loaders would be a whole different beast. For Node, luckily, it's as simple as this, if turning it into a runtime error is permissible (very similar for other cases):
// original
import foo from "./module.js";
// polyfill
var foo;
(function () {
try {
foo = require("./module.js").default;
} catch (e) {
var err = new ImportError();
for (var i in Object.keys(e))
err[i] = e[i];
throw e;
}
})();
For AMD, it would be similar to this:
// original
import foo from "module";
// polyfill
define(["module"], function (foo) {
foo = foo.default;
// module body
}, function (e) {
var err = new ImportError();
for (var i in Object.keys(e))
err[i] = e[i];
throw e;
});
What happens if a module isn't able to be found? Is that implementation defined, or have I missed it in the spec?