Skip to content

Commit

Permalink
feat: duck types errors to avoid issues w/ different instances; remov…
Browse files Browse the repository at this point in the history
…es redundant error normalizatio
  • Loading branch information
rafamel committed May 6, 2019
1 parent 685d023 commit 97f2f8e
Show file tree
Hide file tree
Showing 29 changed files with 128 additions and 145 deletions.
8 changes: 0 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@
"command-join": "^2.0.0",
"common-tags": "^1.8.0",
"concurrently": "^4.1.0",
"errorish": "^0.3.0",
"exits": "^0.4.0",
"find-up": "^3.0.0",
"fs-extra": "^7.0.1",
Expand Down
10 changes: 6 additions & 4 deletions src/bin/kpo.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#!/usr/bin/env node

import main from './main';
import { ensure } from 'errorish';
import errors from '~/utils/errors';
import logger from '~/utils/logger';
import { terminate, state } from 'exits';
import attach from './attach';
import { OWNED_ENV_KEY } from '~/constants';
import { error, isOpenError } from '~/utils/errors';

// Attach exits hooks
attach();
Expand All @@ -17,9 +16,12 @@ process.env[OWNED_ENV_KEY] = 'true';
main(process.argv.slice(2)).catch(async (err) => {
if (state().triggered) return;

err = ensure(err);
err = error(err);
logger.error(err.message);
if (err instanceof errors.OpenError) logger.debug(err);
if (err.root.stack) {
if (isOpenError(err)) logger.error(err.root.stack);
else logger.trace(err.root.stack);
}

return terminate('exit', 1);
});
3 changes: 1 addition & 2 deletions src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import run from './run';
import logger from '~/utils/logger';
import exec from '~/utils/exec';
import { TCoreOptions, IExecOptions, TScript } from '~/types';
import { rejects } from 'errorish';
import { absolute } from '~/utils/file';
import wrapCore from './wrap';
import guardian from '~/utils/guardian';
Expand Down Expand Up @@ -122,7 +121,7 @@ const core = wrapCore(
return typeof item === 'string'
? core.exec(item, args, false, opts)
: item(args);
}).catch(rejects);
});
},
async exec(
command: string,
Expand Down
29 changes: 7 additions & 22 deletions src/core/load.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import path from 'path';
import fs from 'fs-extra';
import yaml from 'js-yaml';
import { rejects } from 'errorish';
import errors from '~/utils/errors';
import { open } from '~/utils/errors';
import { ILoaded, IPaths } from './types';
import { IOfType, IPackageOptions } from '~/types';
import options from './options';
Expand All @@ -15,7 +14,6 @@ export default async function load(paths: IPaths): Promise<ILoaded> {
? await fs
.readJSON(paths.pkg)
.then((pkg) => processPkg(paths.pkg as string, pkg))
.catch(rejects)
: null;

const kpo = paths.kpo ? await loadFile(paths.kpo) : null;
Expand All @@ -30,18 +28,10 @@ export async function loadFile(file: string): Promise<IOfType<any> | null> {
case '.js':
return requireLocal(file);
case '.json':
return fs
.readJSON(file)
.then(processStatic)
.catch(rejects);
return fs.readJSON(file).then(processStatic);
case '.yml':
case '.yaml':
const kpo = yaml.safeLoad(
await fs
.readFile(file)
.then(String)
.catch(rejects)
);
const kpo = yaml.safeLoad(await fs.readFile(file).then(String));
return processStatic(kpo);
default:
throw Error(`Extension not valid for ${file}`);
Expand Down Expand Up @@ -70,17 +60,12 @@ export function processPkg(file: string, pkg: IOfType<any>): IOfType<any> {
}

export async function requireLocal(file: string): Promise<IOfType<any>> {
// Ensure local kpo has equal state
let kpoPath: string | null = null;
let scripts: any;
try {
kpoPath = require.resolve('kpo', { paths: [file] });
} catch (_) {}
if (kpoPath) {
const local = errors.open.throws(() => require(kpoPath as string));
// Overwrite error constructors and helpers
if (local && local.errors) Object.assign(local.errors, errors);
scripts = require(file);
} catch (err) {
throw open(err);
}

const scripts = errors.open.throws(() => require(file));
return typeof scripts === 'function' ? scripts(_public) : scripts;
}
3 changes: 1 addition & 2 deletions src/core/paths/files.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import fs from 'fs-extra';
import path from 'path';
import { rejects } from 'errorish';
import { FILE_NAME, FILE_EXT } from '~/constants';
import { find, exists, absolute } from '~/utils/file';

Expand Down Expand Up @@ -90,7 +89,7 @@ export async function getFromPackage(
if (!pkg) return null;

const dir = path.parse(pkg).dir;
const parsed = await fs.readJSON(pkg).catch(rejects);
const parsed = await fs.readJSON(pkg);

if (!parsed.kpo || !parsed.kpo.file) return null;

Expand Down
8 changes: 2 additions & 6 deletions src/core/paths/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import path from 'path';
import { IPaths } from '../types';
import getPaths from './paths';
import errors from '~/utils/errors';
import { absolute } from '~/utils/file';
import { KpoError } from '~/utils/errors';

/**
* - `file` determines the path for the `kpo.scripts` file; if not passed, it will be resolved from `directory`.
Expand Down Expand Up @@ -34,10 +34,6 @@ export async function getRootPaths(directories: {
return await getPaths({ directory, cwd }, Boolean(root));
} catch (err) {
if (!root) return null;
throw new errors.WrappedError(
`root scope couldn't be retrieved: ${root}`,
null,
err
);
throw new KpoError(`root scope couldn't be retrieved: ${root}`, err);
}
}
4 changes: 2 additions & 2 deletions src/core/run.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logger from '~/utils/logger';
import { TScript } from '~/types';
import errors from '~/utils/errors';
import guardian from '~/utils/guardian';
import { open } from '~/utils/errors';

export default async function run(
script: TScript,
Expand All @@ -26,7 +26,7 @@ export default async function run(
try {
res = await runner(script);
} catch (err) {
throw errors.open.ensure(err);
throw open(err);
}
await run(res, runner);
} else if (Array.isArray(script)) {
Expand Down
3 changes: 1 addition & 2 deletions src/core/scope/children/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import path from 'path';
import fs from 'fs-extra';
import logger from '~/utils/logger';
import { exists } from '~/utils/file';
import { rejects } from 'errorish';
import getChildrenFromGlobs from './from-globs';
import getChildrenFromMap from './from-map';
import { IChild } from '../../types';
Expand All @@ -24,7 +23,7 @@ export default async function getChildren(
}

const lerna = (await exists(path.join(directories.pkg, 'lerna.json')))
? await fs.readJSON(path.join(directories.pkg, 'lerna.json')).catch(rejects)
? await fs.readJSON(path.join(directories.pkg, 'lerna.json'))
: null;

if (lerna) {
Expand Down
9 changes: 4 additions & 5 deletions src/core/tasks/from-kpo.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ITask } from '../types';
import { IScripts } from '~/types';
import purePath from './pure-path';
import errors from '~/utils/errors';
import { KpoError } from '~/utils/errors';

export default function getFromKpo(path: string, kpo: IScripts): ITask {
const task = trunk(purePath(path).split('.'), kpo, '');
Expand Down Expand Up @@ -48,10 +48,9 @@ export function trunk(arr: string[], obj: any, path: string): ITask {
);
}
if (!props.length) {
throw new errors.CustomError(
`There are no tasks matching ${purePath(path ? `${path}.${key}` : key)}`,
{ type: 'NotFound' }
);
throw new KpoError(
`There are no tasks matching ${purePath(path ? `${path}.${key}` : key)}`
).set({ type: 'NotFound' });
}
const actualKey = props.shift() as string;
const task = trunk(
Expand Down
8 changes: 3 additions & 5 deletions src/core/tasks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import getFromKpo from './from-kpo';
import getFromPackage from './from-package';
import { ITask, ITasks } from '../types';
import recursiveFields from './recursive-fields';
import errors from '~/utils/errors';
import { KpoError, isKpoError } from '~/utils/errors';

export function getTask(
path: string,
Expand All @@ -12,11 +12,9 @@ export function getTask(
): ITask {
try {
if (kpo) return getFromKpo(path, kpo);
throw new errors.CustomError(`Task ${path} not found`, {
type: 'NotFound'
});
throw new KpoError(`Task ${path} not found`).set({ type: 'NotFound' });
} catch (err) {
if (!pkg || !err.data || !err.data.type || err.data.type !== 'NotFound') {
if (!pkg || !isKpoError(err) || !err.data || err.data.type !== 'NotFound') {
throw err;
}

Expand Down
6 changes: 3 additions & 3 deletions src/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
import inVersionRange from '~/utils/version-range';
import read from 'read-pkg-up';
import cache from '~/utils/cache';
import errors from '~/utils/errors';
import {
GLOBALS_KEY,
TGlobal,
TEnvironmental,
OWNED_ENV_KEY
} from '~/constants';
import { IOfType } from '~/types';
import { KpoError } from './utils/errors';

const locals = {
globals: {} as { [key in TGlobal]: any },
Expand All @@ -21,8 +21,8 @@ export const pkg = cache(
(): IOfType<any> => {
try {
return read.sync({ cwd: __dirname }).pkg;
} catch (e) {
throw new errors.CustomError(`Package couldn't be retrieved`, null, e);
} catch (err) {
throw new KpoError(`Package couldn't be retrieved`, err);
}
}
);
Expand Down
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export * from './public';
export { default as errors } from './utils/errors';
export * from './types';
10 changes: 3 additions & 7 deletions src/public/exec/parallel.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import core from '~/core';
import { IOfType, IMultiExecOptions } from '~/types';
import logger from '~/utils/logger';
import errors from '~/utils/errors';
import expose from '~/utils/expose';
import join from 'command-join';
import { CONCURRENTLY_PATH } from '~/constants';
import { KpoError } from '~/utils/errors';

/**
* Options taken by `parallel`
Expand Down Expand Up @@ -64,14 +64,10 @@ export function create(): IParallel {
try {
await core.exec(CONCURRENTLY_PATH, argv, true, options);
} catch (e) {
const err = new errors.WrappedError(
'Parallel commands execution failed',
null,
e
);
const err = new KpoError('Parallel commands execution failed', e);
if (options.silent) {
logger.error(err.message);
logger.debug(err);
if (err.root.stack) logger.trace(err.root.stack);
} else {
throw err;
}
Expand Down
5 changes: 2 additions & 3 deletions src/public/exec/stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import join from 'command-join';
import { NODE_PATH, KPO_PATH } from '~/constants';
import { IMultiExecOptions } from '~/types';
import chalk from 'chalk';
import errors from '~/utils/errors';
import logger from '~/utils/logger';
import { KpoError } from '~/utils/errors';

/**
* Options taken by `stream`
Expand Down Expand Up @@ -85,9 +85,8 @@ function stream(
await series
.fn(join(commands[i]), { ...options, cwd: undefined })
.catch(async (err) => {
throw new errors.WrappedError(
throw new KpoError(
`Stream failed for ${children[i].name}: ${join(argv)}`,
null,
err
);
});
Expand Down
13 changes: 5 additions & 8 deletions src/public/fs/copy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { absolute, exists } from '~/utils/file';
import { IFsWriteOptions } from './types';
import expose, { TExposedOverload } from '~/utils/expose';
import confirm from '~/utils/confirm';
import { rejects } from 'errorish';
import logger from '~/utils/logger';

export type TCopyFilterFn =
Expand Down Expand Up @@ -82,12 +81,10 @@ export async function trunk(
const msg = `Copy "${relatives.src}" to "${relatives.dest}"?`;
if (!(await confirm(msg, options))) return;

await fs
.copy(src, dest, {
overwrite: options.overwrite,
errorOnExist: options.fail,
filter
})
.catch(rejects);
await fs.copy(src, dest, {
overwrite: options.overwrite,
errorOnExist: options.fail,
filter
});
logger.info(`Copied: "${relatives.src}" to "${relatives.dest}"`);
}
3 changes: 1 addition & 2 deletions src/public/fs/mkdir.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import path from 'path';
import fs from 'fs-extra';
import { rejects } from 'errorish';
import { absolute, exists } from '~/utils/file';
import confirm from '~/utils/confirm';
import { parallel } from 'promist';
Expand Down Expand Up @@ -65,7 +64,7 @@ function mkdir(
if (!(await confirm('Create?', options))) return;

await parallel.each(nonExistingPaths, async (absolute, i) => {
await fs.ensureDir(absolute).catch(rejects);
await fs.ensureDir(absolute);

const relative = relatives.nonExisting[i];
logger.debug(`Created: ${relative}`);
Expand Down
3 changes: 1 addition & 2 deletions src/public/fs/move.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { absolute, exists } from '~/utils/file';
import { IFsWriteOptions } from './types';
import expose from '~/utils/expose';
import confirm from '~/utils/confirm';
import { rejects } from 'errorish';
import logger from '~/utils/logger';

export default expose(move);
Expand Down Expand Up @@ -67,6 +66,6 @@ export async function trunk(
const msg = `Move "${relatives.src}" to "${relatives.dest}"?`;
if (!(await confirm(msg, options))) return;

await fs.move(src, dest, { overwrite: options.overwrite }).catch(rejects);
await fs.move(src, dest, { overwrite: options.overwrite });
logger.info(`Moved: "${relatives.src}" to "${relatives.dest}"`);
}

0 comments on commit 97f2f8e

Please sign in to comment.