Skip to content

Commit

Permalink
restructure errors to not use a json file
Browse files Browse the repository at this point in the history
  • Loading branch information
terrablue committed Jun 11, 2024
1 parent da0cbda commit d45912a
Show file tree
Hide file tree
Showing 15 changed files with 213 additions and 174 deletions.
5 changes: 4 additions & 1 deletion packages/primate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
},
"type": "module",
"types": "./types/index.d.ts",
"exports": "./src/exports.js",
"exports": {
".": "./src/exports.js",
"./errors": "./src/errors.js"
},
"scripts": {
"prepublishOnly": "dts-buddy"
}
Expand Down
4 changes: 1 addition & 3 deletions packages/primate/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ import { MediaType, Status } from "rcompat/http";
import { is } from "rcompat/invariant";
import * as O from "rcompat/object";
import { globify } from "rcompat/string";
import errors from "./errors.js";
import { DoubleFileExtension } from "primate/errors";
import * as handlers from "./handlers.js";
import * as loaders from "./loaders/exports.js";
import to_sorted from "./to_sorted.js";

const { DoubleFileExtension } = errors;

const to_csp = (config_csp, assets, csp) => config_csp
// only csp entries in the config will be enriched
.map(([key, directives]) =>
Expand Down
4 changes: 2 additions & 2 deletions packages/primate/src/dispatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { is } from "rcompat/invariant";
import * as O from "rcompat/object";
import { camelcased } from "rcompat/string";
import { tryreturn } from "rcompat/sync";
import errors from "./errors.js";
import { MismatchedType } from "primate/errors";
import validate from "./validate.js";

export default (patches = {}) => (object, raw, cased = true) => {
return Object.assign(Object.create(null), {
...O.map(patches, ([name, patch]) => [`get${camelcased(name)}`, key => {
is(key).defined(`\`${name}\` called without key`);
return tryreturn(_ => validate(patch, object[key], key))
.orelse(({ message }) => errors.MismatchedType.throw(message));
.orelse(({ message }) => MismatchedType.throw(message));
}]),
get(key) {
is(key).string();
Expand Down
181 changes: 178 additions & 3 deletions packages/primate/src/errors.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,181 @@
import { File } from "rcompat/fs";
import Logger from "./Logger.js";

const json = await new File(import.meta.url).up(1).join("errors.json").json();
const json = {
errors: {
DoubleFileExtension: {
message: "double file extension {0}",
fix: "unload one of the two handlers registering the file extension",
level: "Error",
},
DoubleModule: {
message: "double module {0} in {1}",
fix: "load {0} only once",
level: "Error",
},
DoublePathParameter: {
message: "double path parameter {0} in route {1}",
fix: "disambiguate path parameters in route names",
level: "Error",
},
DoubleRoute: {
message: "double route of the form {0}",
fix: "disambiguate routes",
level: "Error",
},
EmptyConfigFile: {
message: "empty config file at {0}",
fix: "add configuration options to the file or remove it",
level: "Warn",
},
EmptyPathParameter: {
message: "empty path parameter {0} in route {1}",
fix: "name the parameter or remove it",
level: "Error",
},
EmptyRouteFile: {
message: "empty route file at {0}",
fix: "add routes to the file or remove it",
level: "Warn",
},
EmptyDirectory: {
message: "empty {0} directory",
fix: "populate {1} or remove it",
level: "Warn",
},
ErrorInConfigFile: {
message: "error in config file: {0}",
fix: "check errors in config file by running {1}",
level: "Error",
},
BadBody: {
message: "bad body returned from route, got {0}",
fix: "return a proper body from route",
level: "Error",
},
BadDefaultExport: {
message: "bad default export at {0}",
fix: "use only functions for the default export",
level: "Error",
},
BadPath: {
message: "bad path {0}",
fix: "use only letters, digits, '_', '[', ']' or '=' in path filenames",
level: "Error",
},
BadTypeExport: {
message: "bad type export at {0}",
fix: "export object with a `base` string and a `validate` function",
level: "Error",
},
BadTypeName: {
message: "bad type name {0}",
fix: "use lowercase-first latin letters and decimals in type names",
level: "Error",
},
MismatchedBody: {
message: "{0}: {1}",
fix: "make sure the body payload corresponds to the used content type",
level: "Error",
},
MismatchedPath: {
message: "mismatched path {0}: {1}",
fix: "fix the type or the caller",
level: "Info",
},
MismatchedType: {
message: "mismatched type: {0}",
fix: "fix the type or the caller",
level: "Info",
},
ModuleNoHooks: {
message: "module {0} has no hooks",
fix: "ensure every module uses at least one hook or deactivate it",
level: "Warn",
},
ModuleNoName: {
message: "module at index {0} has no name",
fix: "update module at index {0} and inform maintainer",
level: "Error",
},
ModulesArray: {
message: "the {0} config property must be an array",
fix: "change {0} to an array in the config or remove this property",
level: "Error",
},
NoHandler: {
message: "no handler for {0}",
fix: "add handler module for this component or remove {0}",
level: "Error",
},
NoRouteToPath: {
message: "no {0} route to {1}",
fix: "create a {0} route function at {2}.js",
level: "Info",
},
OptionalRoute: {
message: "optional route {0} must be a leaf",
fix: "move route to leaf (last) position in filesystem hierarchy",
level: "Error",
},
ReservedTypeName: {
message: "reserved type name {0}",
fix: "do not use any reserved type names",
level: "Error",
},
RestRoute: {
message: "rest route {0} must be a leaf",
fix: "move route to leaf (last) position in filesystem hierarchy",
level: "Error",
},
},
};

export default Logger.err(json.errors, json.module);
const errors = Logger.err(json.errors, "primate");

const {
DoubleFileExtension,
EmptyConfigFile,
ErrorInConfigFile,
MismatchedType,
NoHandler,
BadBody,
MismatchedBody,
MismatchedPath,
NoRouteToPath,
DoubleRoute,
OptionalRoute,
RestRoute,
EmptyDirectory,
ModulesArray,
ModuleNoName,
ModuleNoHooks,
DoubleModule,
BadTypeExport,
BadTypeName,
ReservedTypeName,
} = errors;

export {
DoubleFileExtension,
DoubleModule,
EmptyConfigFile,
ErrorInConfigFile,
MismatchedType,
NoHandler,
BadBody,
MismatchedBody,
MismatchedPath,
NoRouteToPath,
DoubleRoute,
OptionalRoute,
RestRoute,
EmptyDirectory,
ModulesArray,
ModuleNoName,
ModuleNoHooks,
BadTypeExport,
BadTypeName,
ReservedTypeName,
};

export default errors;
130 changes: 0 additions & 130 deletions packages/primate/src/errors.json

This file was deleted.

5 changes: 2 additions & 3 deletions packages/primate/src/handlers.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { NoHandler } from "primate/errors";
import { File } from "rcompat/fs";
import { identity } from "rcompat/function";
import { MediaType, Status } from "rcompat/http";
import { HTML } from "rcompat/string";
import errors from "./errors.js";

/**
* @typedef {import("./types").MinOptions} MinOptions
Expand Down Expand Up @@ -136,8 +136,7 @@ const extensions = ["fullExtension", "extension"];
const view = (name, props, options) => (app, ...rest) => extensions
.map(extension => app.extensions[new File(name)[extension]])
.find(extension => extension?.handle)
?.handle(name, props, options)(app, ...rest)
?? errors.NoHandlerForComponent.throw(name);
?.handle(name, props, options)(app, ...rest) ?? NoHandler.throw(name);
// }}}

export { error, html, json, redirect, sse, stream, text, view, ws };
2 changes: 1 addition & 1 deletion packages/primate/src/hooks/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import copy_includes from "./copy_includes.js";
import $router from "./router.js";

const html = /^.*.html$/u;
const defaults = (await P.root(import.meta.url)).join("src/defaults");

const pre = async (app, mode) => {
app.log.system(`starting ${dim(mode)} build`);
Expand Down Expand Up @@ -44,6 +43,7 @@ const pre = async (app, mode) => {
const post = async app => {
const location = app.get("location");
const { path } = app;
const defaults = (await P.root(import.meta.url)).join("src/defaults");

// stage routes
if (await path.routes.exists()) {
Expand Down
Loading

0 comments on commit d45912a

Please sign in to comment.