Skip to content

Commit

Permalink
refactor(logger 🔧): task error logging (#454)
Browse files Browse the repository at this point in the history
  • Loading branch information
phenomnomnominal authored Jan 27, 2021
1 parent b8f1f68 commit 5d0810b
Show file tree
Hide file tree
Showing 27 changed files with 180 additions and 111 deletions.
2 changes: 0 additions & 2 deletions goldens/api/@betterer/errors.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,3 @@ export declare type BettererErrorDetail = string | Error | BettererError;
export declare type BettererErrorDetails = ReadonlyArray<BettererErrorDetail>;

export declare function isBettererError(err: unknown): err is BettererError;

export declare function logErrorΔ(err: Error | BettererError): void;
3 changes: 2 additions & 1 deletion goldens/api/@betterer/logger.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ export declare type BettererTasksState = {
running: number;
done: number;
errors: number;
error: Error | null;
startTime: number;
shouldExit: boolean;
};

export declare type BettererTaskStatusUpdate = (status: string) => void;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"test:extension": "lerna run test:extension",
"prepublishOnly": "yarn run build"
},
"engines": {
"engines": {
"node": ">=12"
},
"types": "test/betterer-public-api.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/betterer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ async function run(): Promise<void> {
const configPath = path.resolve(cwd, './.betterer.ts');
const resultsPath = path.resolve(cwd, './.betterer.results');
const { worse } = await betterer({ configPath, resultsPath, cwd });
process.exitcode = worse.length !== 0 ? 1 : 0;
process.exitCode = worse.length !== 0 ? 1 : 0;
}
```
2 changes: 1 addition & 1 deletion packages/betterer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"compile": "tsc -b .",
"api": "ts-api-guardian --out ../../goldens/api/@betterer/betterer.d.ts dist/index.d.ts"
},
"engines": {
"engines": {
"node": ">=12"
},
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"compile": "tsc -b .",
"api": "ts-api-guardian --out ../../goldens/api/@betterer/cli.d.ts dist/index.d.ts"
},
"engines": {
"engines": {
"node": ">=12"
},
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/constraints/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"compile": "tsc -b .",
"api": "ts-api-guardian --out ../../goldens/api/@betterer/constraints.d.ts dist/index.d.ts"
},
"engines": {
"engines": {
"node": ">=12"
},
"dependencies": {
Expand Down
18 changes: 1 addition & 17 deletions packages/errors/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

[![npm version](https://img.shields.io/npm/v/@betterer/errors.svg)](https://www.npmjs.com/package/@betterer/errors)

Error handler used within [**`Betterer`**](https://github.com/phenomnomnominal/betterer).
Error type used within [**`Betterer`**](https://github.com/phenomnomnominal/betterer).

## Usage

Expand All @@ -17,19 +17,3 @@ import { BettererError } from '@betterer/errors';

const error = new BettererError(`Something went wrong: "OOPS!"`, { some: 'details' });
```

### Log Error

> ## 🚨🚨🚨 THIS FUNCTION SHOULD ONLY BE USED WITHIN THE BETTERER MONOREPO 🚨🚨🚨
Log a registered error type:

```typescript
import { BettererError, logErrorΔ } from '@betterer/errors';

try {
throw new BettererError(`something went wrong: "OOPS!"`):
} catch (e) {
logErrorΔ(e); // 'Something went wrong: "OOPS"'
}
```
5 changes: 1 addition & 4 deletions packages/errors/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@
"compile": "tsc -b .",
"api": "ts-api-guardian --out ../../goldens/api/@betterer/errors.d.ts dist/index.d.ts"
},
"engines": {
"engines": {
"node": ">=12"
},
"dependencies": {
"@betterer/logger": "^3.1.1"
}
}
23 changes: 0 additions & 23 deletions packages/errors/src/error-handler.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/errors/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export { BettererError, isBettererError } from './error';
export { logErrorΔ } from './error-handler';
export { BettererErrorDetail, BettererErrorDetails } from './types';
7 changes: 1 addition & 6 deletions packages/errors/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,5 @@
"rootDir": "./src"
},
"include": ["./src/*.ts"],
"exclude": ["../node_modules/*", "./node_modules/*", "./dist/*"],
"references": [
{
"path": "../logger"
}
]
"exclude": ["../node_modules/*", "./node_modules/*", "./dist/*"]
}
2 changes: 1 addition & 1 deletion packages/eslint/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"compile": "tsc -b .",
"api": "ts-api-guardian --out ../../goldens/api/@betterer/eslint.d.ts dist/index.d.ts"
},
"engines": {
"engines": {
"node": ">=12"
},
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/fixture/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"compile": "tsc -b .",
"api": "ts-api-guardian --out ../../goldens/api/@betterer/fixture.d.ts dist/index.d.ts"
},
"engines": {
"engines": {
"node": ">=12"
},
"dependencies": {
Expand Down
3 changes: 2 additions & 1 deletion packages/logger/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@
"compile": "tsc -b .",
"api": "ts-api-guardian --out ../../goldens/api/@betterer/logger.d.ts dist/index.d.ts"
},
"engines": {
"engines": {
"node": ">=12"
},
"dependencies": {
"@babel/code-frame": "^7.10.3",
"@betterer/errors": "^3.1.1",
"chalk": "^4.1.0",
"ink": "^3.0.7",
"jest-diff": "^26.6.2",
Expand Down
46 changes: 46 additions & 0 deletions packages/logger/src/components/tasks/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { BettererError, isBettererError } from '@betterer/errors';
import { Box, Text } from 'ink';
import React, { FC } from 'react';

export type BettererTaskErrorProps = {
error: Error | BettererError;
};

let errorCount = 0;
let detailCount = 0;

export const BettererTaskError: FC<BettererTaskErrorProps> = function BettererTaskError({ error }) {
let errors: Array<Error | BettererError> = [];
let details: Array<string> = [];
if (isBettererError(error)) {
errors = error.details.filter((detail) => isError(detail)) as Array<Error | BettererError>;
details = error.details.filter((detail) => !isError(detail)) as Array<string>;
}
return (
<>
<Box flexDirection="column" paddingTop={1}>
<Box>
<Text color="redBright">Error: </Text>
<Text>{error.message}</Text>
</Box>
{error.stack && (
<Box paddingLeft={2} paddingTop={1}>
<Text>{error.stack}</Text>
</Box>
)}
{details.map((detail) => (
<Box key={detailCount++} paddingTop={1}>
<Text>{detail.trim()}</Text>
</Box>
))}
</Box>
{errors.map((error) => (
<BettererTaskError key={errorCount++} error={error} />
))}
</>
);
};

function isError(value: unknown): value is Error | BettererError {
return (value as Error).message != null && (value as Error).stack !== null;
}
41 changes: 33 additions & 8 deletions packages/logger/src/components/tasks/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ export type BettererTasksState = {
running: number;
done: number;
errors: number;
error: Error | null;
startTime: number;
shouldExit: boolean;
};

export type BettererTasksAction =
Expand All @@ -14,28 +15,52 @@ export type BettererTasksAction =
| {
type: 'stop';
}
| { type: 'error'; error: Error };
| {
type: 'error';
};

export type BettererTasksContextType = Dispatch<BettererTasksAction>;

export const INITIAL_STATE: BettererTasksState = {
running: 0,
done: 0,
errors: 0,
error: null
startTime: Date.now(),
shouldExit: false
};

export const BettererTasksContext = createContext<BettererTasksContextType>(() => void 0);

export function reducer(state: BettererTasksState, action: BettererTasksAction): BettererTasksState {
switch (action.type) {
case 'start':
return { ...state, running: state.running + 1 };
case 'stop':
return { ...state, running: state.running - 1, done: state.done + 1 };
case 'error':
return { ...state, running: state.running - 1, errors: state.errors + 1, error: action.error };
return {
...state,
running: state.running + 1
};
case 'stop': {
const newState = {
...state,
running: state.running - 1,
done: state.done + 1
};
return getShouldExit(newState);
}
case 'error': {
const newState = {
...state,
running: state.running - 1,
done: state.done + 1,
errors: state.errors + 1
};
return getShouldExit(newState);
}
default:
return state;
}
}

function getShouldExit(state: BettererTasksState): BettererTasksState {
const shouldExit = state.running === 0;
return { ...state, shouldExit };
}
33 changes: 16 additions & 17 deletions packages/logger/src/components/tasks/task.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import React, { FC, useContext, useEffect, useState } from 'react';

import { BettererLoggerCodeInfo } from '../../types';
import { codeΔ } from '../../code';
import { BettererTaskError } from './error';
import { BettererTasksContext } from './state';
import { BettererTaskStatus } from './status';
import { BettererTaskContext, BettererTaskLog, BettererTaskLogs } from './types';
import { BettererTaskContext, BettererTaskLog } from './types';
import { useTaskLogs } from './use-task-logs';

export type BettererTaskProps = {
context: BettererTaskContext;
Expand All @@ -17,16 +19,11 @@ export const BettererTask: FC<BettererTaskProps> = function BettererTask({ conte
const { name, run } = context;
const [running, setRunning] = useState(true);
const [status, setStatus] = useState<BettererTaskLog | null>(null);
const [logMessages, setLogMessages] = useState<BettererTaskLogs>([]);
const [messageLogs, setMessageLogs] = useTaskLogs();
const [error, setError] = useState<Error | null>(null);

useEffect(() => {
void (async () => {
let runLogMessages: BettererTaskLogs = [];
function addLogMessage(log: BettererTaskLog) {
runLogMessages = [...runLogMessages, log];
setLogMessages(runLogMessages);
}

function statusError(status: string): void {
setStatus(['🔥', 'redBright', status]);
}
Expand All @@ -41,22 +38,22 @@ export const BettererTask: FC<BettererTaskProps> = function BettererTask({ conte
const { message } = codeInfo;
const codeFrame = codeΔ(codeInfo);
logInfo(message.trim());
addLogMessage(['💻', 'magentaBright', codeFrame]);
setMessageLogs(['💻', 'magentaBright', codeFrame]);
}
function logDebug(log: string): void {
addLogMessage(['🤯', 'blueBright', log]);
setMessageLogs(['🤯', 'blueBright', log]);
}
function logError(log: string): void {
addLogMessage(['🔥', 'redBright', log]);
setMessageLogs(['🔥', 'redBright', log]);
}
function logInfo(log: string): void {
addLogMessage(['💭', 'gray', log]);
setMessageLogs(['💭', 'gray', log]);
}
function logSuccess(log: string): void {
addLogMessage(['✅', 'greenBright', log]);
setMessageLogs(['✅', 'greenBright', log]);
}
function logWarning(log: string): void {
addLogMessage(['🚨', 'yellowBright', log]);
setMessageLogs(['🚨', 'yellowBright', log]);
}

dispatch({ type: 'start' });
Expand All @@ -82,7 +79,8 @@ export const BettererTask: FC<BettererTaskProps> = function BettererTask({ conte
dispatch({ type: 'stop' });
} catch (error) {
statusError((error as Error).message);
dispatch({ type: 'error', error: error as Error });
setError(error);
dispatch({ type: 'error' });
process.exitCode = 1;
}
setRunning(false);
Expand All @@ -92,13 +90,14 @@ export const BettererTask: FC<BettererTaskProps> = function BettererTask({ conte
return (
<Box flexDirection="column">
{!running && status && <BettererTaskStatus name={name} status={status} />}
{logMessages.length ? (
{messageLogs.length ? (
<Box flexDirection="column">
{logMessages.map((log, index) => (
{messageLogs.map((log, index) => (
<Text key={`${name}-log-${index}`}>{prependLogBlock(log)}</Text>
))}
</Box>
) : null}
{error && <BettererTaskError error={error} />}
{running && status && <BettererTaskStatus name={name} status={status} />}
</Box>
);
Expand Down
Loading

0 comments on commit 5d0810b

Please sign in to comment.