Skip to content

Commit

Permalink
feat(runtime): capture stack trace from $ call's (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
c4spar authored Jul 10, 2022
1 parent 9cc7ec9 commit 7c06a04
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 18 deletions.
4 changes: 3 additions & 1 deletion src/runtime/exec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ export function exec(
console.log($.brightBlue("$ %s"), cmd);
}

return new Process(cmd);
return new Process(cmd, {
errorContext: exec,
});
}

/**
Expand Down
33 changes: 21 additions & 12 deletions src/runtime/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import { Deferred, deferred } from "./deps.ts";
import { ProcessError } from "./process_error.ts";
import { ProcessOutput } from "./process_output.ts";

export interface ProcessOptions {
// deno-lint-ignore ban-types
errorContext?: Function;
}

export class Process implements Promise<ProcessOutput> {
readonly [Symbol.toStringTag] = "Process";
readonly #cmd: string;
Expand All @@ -12,9 +17,17 @@ export class Process implements Promise<ProcessOutput> {
#stdin: Deno.RunOptions["stdin"] = "inherit";
#stdout: Deno.RunOptions["stdout"] = $.stdout;
#stderr: Deno.RunOptions["stderr"] = $.stderr;
#baseError: ProcessError;

constructor(cmd: string) {
constructor(cmd: string, { errorContext }: ProcessOptions = {}) {
this.#cmd = cmd;
this.#baseError = new ProcessError({
combined: "",
stderr: "",
stdout: "",
status: { code: 1, success: false, signal: undefined },
});
Error.captureStackTrace(this.#baseError, errorContext);
}

get #process(): Deno.Process {
Expand Down Expand Up @@ -82,22 +95,18 @@ export class Process implements Promise<ProcessOutput> {
this.#process.stderr &&
read(this.#process.stderr, [stderr, combined], Deno.stderr),
]);

if (!status.success) {
throw new ProcessError({
stdout: stdout.join(""),
stderr: stderr.join(""),
combined: combined.join(""),
status,
});
}

return new ProcessOutput({
const output = new ProcessOutput({
stdout: stdout.join(""),
stderr: stderr.join(""),
combined: combined.join(""),
status,
});

if (!status.success) {
throw ProcessError.merge(this.#baseError, new ProcessError(output));
}

return output;
} finally {
this.#process.close();
this.#process.stdin?.close();
Expand Down
22 changes: 17 additions & 5 deletions src/runtime/process_error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ export class ProcessError extends Error {
#combined!: string;
#status!: Deno.ProcessStatus;

static merge(target: ProcessError, source: ProcessError): ProcessError {
target.#name = source.name;
target.#merge(source);
return target;
}

constructor(options: ProcessErrorOptions) {
super();
Object.setPrototypeOf(this, ProcessError.prototype);
this.#stdout = options.stdout;
this.#stderr = options.stderr;
this.#combined = options.combined;
this.#status = options.status;
this.message = this.#getErrorMessage();
this.#merge(options);
}

get name(): string {
Expand All @@ -41,6 +43,16 @@ export class ProcessError extends Error {
return this.#status;
}

#merge(
{ stdout, stderr, combined, status }: ProcessErrorOptions,
): void {
this.#stdout = stdout;
this.#stderr = stderr;
this.#combined = combined;
this.#status = status;
this.message = this.#getErrorMessage();
}

#getErrorMessage(): string {
let message = colors.bold("Command failed.");

Expand Down

0 comments on commit 7c06a04

Please sign in to comment.