Skip to content

Commit

Permalink
feat(endo): Improve JSON file parse error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
kriskowal committed Aug 25, 2020
1 parent 7fe9ff2 commit 677a949
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 17 deletions.
7 changes: 6 additions & 1 deletion packages/endo/src/archive.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { parseExtension } from "./extension.js";
import { compartmentMapForNodeModules } from "./compartmap.js";
import { search } from "./search.js";
import { assemble } from "./assemble.js";
import * as json from "./json.js";

const { entries, freeze, fromEntries, values } = Object;

Expand Down Expand Up @@ -165,10 +166,14 @@ export const makeArchive = async (read, moduleLocation) => {
const {
packageLocation,
packageDescriptorText,
packageDescriptorLocation,
moduleSpecifier
} = await search(read, moduleLocation);

const packageDescriptor = JSON.parse(packageDescriptorText);
const packageDescriptor = json.parse(
packageDescriptorText,
packageDescriptorLocation
);
const compartmentMap = await compartmentMapForNodeModules(
read,
packageLocation,
Expand Down
17 changes: 10 additions & 7 deletions packages/endo/src/compartmap.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint no-shadow: 0 */

import { inferExports } from "./infer-exports.js";
import * as json from "./json.js";

const { create, entries, keys, values } = Object;

Expand All @@ -9,7 +10,7 @@ const decoder = new TextDecoder();
// q, as in quote, for enquoting strings in error messages.
const q = JSON.stringify;

const resolve = (rel, abs) => new URL(rel, abs).toString();
const resolveLocation = (rel, abs) => new URL(rel, abs).toString();

const basename = location => {
const { pathname } = new URL(location);
Expand All @@ -21,13 +22,15 @@ const basename = location => {
};

const readDescriptor = async (read, packageLocation) => {
const descriptorPath = resolve("package.json", packageLocation);
const descriptorBytes = await read(descriptorPath).catch(_error => undefined);
const descriptorLocation = resolveLocation("package.json", packageLocation);
const descriptorBytes = await read(descriptorLocation).catch(
_error => undefined
);
if (descriptorBytes === undefined) {
return undefined;
}
const descriptorText = decoder.decode(descriptorBytes);
const descriptor = JSON.parse(descriptorText);
const descriptor = json.parse(descriptorText, descriptorLocation);
return descriptor;
};

Expand All @@ -49,22 +52,22 @@ const readDescriptorWithMemo = async (memo, read, packageLocation) => {
// find it efficiently.
const findPackage = async (readDescriptor, directory, name) => {
for (;;) {
const packageLocation = resolve(`node_modules/${name}/`, directory);
const packageLocation = resolveLocation(`node_modules/${name}/`, directory);
// eslint-disable-next-line no-await-in-loop
const packageDescriptor = await readDescriptor(packageLocation);
if (packageDescriptor !== undefined) {
return { packageLocation, packageDescriptor };
}

const parent = resolve("../", directory);
const parent = resolveLocation("../", directory);
if (parent === directory) {
return undefined;
}
directory = parent;

const base = basename(directory);
if (base === "node_modules") {
directory = resolve("../", directory);
directory = resolveLocation("../", directory);
if (parent === directory) {
return undefined;
}
Expand Down
3 changes: 2 additions & 1 deletion packages/endo/src/import-archive.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { readZip } from "./zip.js";
import { assemble } from "./assemble.js";
import { parserForLanguage } from "./parse.js";
import * as json from "./json.js";

const decoder = new TextDecoder();

Expand Down Expand Up @@ -35,7 +36,7 @@ export const parseArchive = async (archiveBytes, archiveLocation) => {

const compartmentMapBytes = await archive.read("compartmap.json");
const compartmentMapText = decoder.decode(compartmentMapBytes);
const compartmentMap = JSON.parse(compartmentMapText);
const compartmentMap = json.parse(compartmentMapText, "compartmap.json");

const execute = (endowments, modules) => {
const { compartments, entry: moduleSpecifier } = compartmentMap;
Expand Down
7 changes: 6 additions & 1 deletion packages/endo/src/import.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { compartmentMapForNodeModules } from "./compartmap.js";
import { search } from "./search.js";
import { assemble } from "./assemble.js";
import { parseExtension } from "./extension.js";
import * as json from "./json.js";

const decoder = new TextDecoder();

Expand Down Expand Up @@ -72,10 +73,14 @@ export const loadLocation = async (read, moduleLocation) => {
const {
packageLocation,
packageDescriptorText,
packageDescriptorLocation,
moduleSpecifier
} = await search(read, moduleLocation);

const packageDescriptor = JSON.parse(packageDescriptorText);
const packageDescriptor = json.parse(
packageDescriptorText,
packageDescriptorLocation
);
const compartmentMap = await compartmentMapForNodeModules(
read,
packageLocation,
Expand Down
7 changes: 7 additions & 0 deletions packages/endo/src/json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const parse = (source, location) => {
try {
return JSON.parse(source);
} catch (error) {
throw new SyntaxError(`Cannot parse JSON from ${location}, ${error}`);
}
};
9 changes: 2 additions & 7 deletions packages/endo/src/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { parseRequires } from "./parse-requires.js";
import { parseExtension } from "./extension.js";
import * as json from "./json.js";

const { entries, freeze, fromEntries } = Object;

Expand Down Expand Up @@ -73,13 +74,7 @@ export const parseCjs = (source, _specifier, location, packageLocation) => {
export const parseJson = (source, _specifier, location, _packageLocation) => {
const imports = freeze([]);
const execute = exports => {
try {
exports.default = JSON.parse(source);
} catch (error) {
throw new SyntaxError(
`Cannot parse JSON module at ${location}, ${error}`
);
}
exports.default = json.parse(source, location);
};
return {
parser: "json",
Expand Down
1 change: 1 addition & 0 deletions packages/endo/src/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const search = async (read, moduleLocation) => {
return {
packageLocation: directory,
packageDescriptorText,
packageDescriptorLocation,
moduleSpecifier: relativize(relative(directory, moduleLocation))
};
}
Expand Down

0 comments on commit 677a949

Please sign in to comment.