Skip to content

Commit

Permalink
improve trace utils
Browse files Browse the repository at this point in the history
  • Loading branch information
uriva committed Sep 24, 2023
1 parent 13bc21e commit 0c05e24
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 34 deletions.
29 changes: 4 additions & 25 deletions src/composition.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { last, reverse } from "./array.ts";
import { reverse } from "./array.ts";
import { AnyAsync, Func, Last, ReturnTypeUnwrapped } from "./typing.ts";

import { not } from "./operator.ts";
import { reduce } from "./reduce.ts";
import { currentLocation } from "./trace.ts";

type UnaryFn<A, R> = (a: A) => R;
type Arg<F extends Func> = Parameters<F>[0];
Expand Down Expand Up @@ -34,35 +35,13 @@ const pipeWithoutStack = <Fs extends Func[]>(
Fs
>;

interface StackFrame {
file: string;
line: number;
column: number;
}

const frameToString = ({ line, file, column }: StackFrame) =>
`${file}:${line}:${column}`;

const parseStackLine = (stackLine: string): null | StackFrame => {
const matches = RegExp(/\s+at\s+(.+\s)?\(?(.+):(\d+):(\d+)\)?/).exec(
stackLine,
);
if (!matches) return null;
const [, , file, line, column] = matches;
return { file, line: parseInt(line), column: parseInt(column) };
};

const parseStackTrace = (trace: string) =>
parseStackLine(last(trace.split("\n")));

const errorBoundry = <F extends Func>(f: F) => {
const err = new Error().stack as string;
const codeLocation = currentLocation();
return ((...x) => {
try {
return f(...x);
} catch (e) {
const lastStackCall = parseStackTrace(err);
if (lastStackCall) console.error(frameToString(lastStackCall));
console.error(codeLocation);
throw e;
}
}) as F;
Expand Down
22 changes: 13 additions & 9 deletions src/debug.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,41 @@
import { Func, ReturnTypeUnwrapped } from "./typing.ts";

import { currentLocation } from "./trace.ts";
import { sideEffect } from "./composition.ts";

export const sideLog = <T>(x: T) => {
console.log(x);
console.log(currentLocation(), x);
return x;
};

export const sideLogAfter = <F extends Func>(f: F): F =>
((...xs) => {
export const sideLogAfter = <F extends Func>(f: F): F => {
const codeLocation = currentLocation();
return ((...xs) => {
const output = f(...xs);
if (output instanceof Promise) {
return output.then((x) => {
console.log(x);
console.log(codeLocation, x);
return x;
}) as ReturnType<F>;
}
console.log(output);
console.log(codeLocation, output);
return output;
}) as F;
};

export const sideLogBefore = <F extends Func>(f: F): F =>
((...xs) => {
console.log(xs.length === 1 ? xs[0] : xs);
export const sideLogBefore = <F extends Func>(f: F): F => {
const codeLocation = currentLocation();
return ((...xs) => {
console.log(codeLocation, xs.length === 1 ? xs[0] : xs);
const output = f(...xs);
if (output instanceof Promise) {
return output.then((x) => {
return x;
}) as ReturnType<F>;
}
console.log(output);
return output;
}) as F;
};

export const sideLogTable = sideEffect(console.table);
// deno-lint-ignore no-explicit-any
Expand Down
22 changes: 22 additions & 0 deletions src/trace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
interface StackFrame {
file: string;
line: number;
column: number;
}
const frameToString = ({ line, file, column }: StackFrame) =>
`${file}:${line}:${column}`;

const parseStackLine = (stackLine: string): StackFrame => {
const matches = RegExp(/\s+at\s+(.+\s)?\(?(.+):(\d+):(\d+)\)?/).exec(
stackLine,
);
if (!matches) throw new Error("could not figure out stack line");
const [, , file, line, column] = matches;
return { file, line: parseInt(line), column: parseInt(column) };
};

const parseStackTrace = (trace: string, picker: (lines: string[]) => string) =>
parseStackLine(picker(trace.split("\n")));

export const currentLocation = () =>
frameToString(parseStackTrace(new Error().stack as string, (x) => x[3]));

0 comments on commit 0c05e24

Please sign in to comment.