Skip to content

Commit

Permalink
Add better error handling (#14395)
Browse files Browse the repository at this point in the history
  • Loading branch information
HenryNguyen5 authored Sep 11, 2024
1 parent bfb66fa commit bd62d0d
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 16 deletions.
97 changes: 97 additions & 0 deletions .github/scripts/jira/axios.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import {
AxiosRequestConfig,
AxiosResponse,
AxiosError,
InternalAxiosRequestConfig,
} from "axios";
import { Readable } from "stream";

interface AxiosErrorFormat<Data = any> {
config: Pick<AxiosRequestConfig, (typeof CONFIG_KEYS)[number]>;
code?: string;
response: Partial<Pick<AxiosResponse<Data>, (typeof RESPONSE_KEYS)[number]>>;
isAxiosError: boolean;
}

interface AxiosErrorFormatError<Data = any>
extends Error,
AxiosErrorFormat<Data> {}

export function formatAxiosError<Data = any>(
origErr: AxiosError<Data>
): AxiosErrorFormatError<Data> {
const { message, name, stack, code, config, response, isAxiosError } =
origErr;

const err: AxiosErrorFormatError = {
...new Error(message),
name,
stack,
code,
isAxiosError,
config: {},
response: {},
};

for (const k of CONFIG_KEYS) {
if (config?.[k] === undefined) {
continue;
}

err.config[k] = formatValue(config[k], k);
}

for (const k of RESPONSE_KEYS) {
if (response?.[k] === undefined) {
continue;
}

err.response[k] = formatValue(response[k], k);
}

return err as any;
}

const CONFIG_KEYS: (keyof InternalAxiosRequestConfig)[] = [
"url",
"method",
"baseURL",
"params",
"data",
"timeout",
"timeoutErrorMessage",
"withCredentials",
"auth",
"responseType",
"xsrfCookieName",
"xsrfHeaderName",
"maxContentLength",
"maxBodyLength",
"maxRedirects",
"socketPath",
"proxy",
"decompress",
] as const;

const RESPONSE_KEYS: (keyof AxiosResponse)[] = [
"data",
"status",
"statusText",
] as const;

function formatValue(
value: any,
key: (typeof CONFIG_KEYS)[number] | (typeof RESPONSE_KEYS)[number]
): any {
if (key !== "data") {
return value;
}

if (process.env.BROWSER !== "true") {
if (value instanceof Readable) {
return "[Readable]";
}
}

return value;
}
26 changes: 18 additions & 8 deletions .github/scripts/jira/create-jira-traceability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
generateIssueLabel,
generateJiraIssuesLink,
getJiraEnvVars,
handleError,
} from "./lib";
import * as core from "@actions/core";

Expand Down Expand Up @@ -191,15 +192,24 @@ async function main() {

const client = createJiraClient();
const label = generateIssueLabel(product, baseRef, headRef);
await addTraceabillityToJiraIssues(
client,
jiraIssueNumbers,
label,
artifactUrl
);
try {
await addTraceabillityToJiraIssues(
client,
jiraIssueNumbers,
label,
artifactUrl
);
} catch (e) {
handleError(e);

const { jiraHost } = getJiraEnvVars()
core.summary.addLink("Jira Issues", generateJiraIssuesLink(`${jiraHost}/issues/`, label));
process.exit(1);
}

const { jiraHost } = getJiraEnvVars();
core.summary.addLink(
"Jira Issues",
generateJiraIssuesLink(`${jiraHost}/issues/`, label)
);
core.summary.write();
}
main();
4 changes: 2 additions & 2 deletions .github/scripts/jira/enforce-jira-issue.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as core from "@actions/core";
import jira from "jira.js";
import { createJiraClient, getGitTopLevel, parseIssueNumberFrom } from "./lib";
import { createJiraClient, getGitTopLevel, handleError, parseIssueNumberFrom } from "./lib";
import { promises as fs } from "fs";
import { join } from "path";

Expand Down Expand Up @@ -36,7 +36,7 @@ async function doesIssueExist(

return true;
} catch (e) {
core.debug(e as any);
handleError(e)
return false;
}
}
Expand Down
18 changes: 17 additions & 1 deletion .github/scripts/jira/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import * as jira from "jira.js";
import { exec } from "child_process";
import { promisify } from "util";
import { join } from "path";

import { isAxiosError } from "axios";
import { formatAxiosError } from "./axios";
export function generateJiraIssuesLink(baseUrl: string, label: string) {
// https://smartcontract-it.atlassian.net/issues/?jql=labels%20%3D%20%22review-artifacts-automation-base%3A8d818ea265ff08887e61ace4f83364a3ee149ef0-head%3A3c45b71f3610de28f429cef0163936eaa448e63c%22
const jqlQuery = `labels = "${label}"`;
Expand Down Expand Up @@ -129,3 +130,18 @@ export function createJiraClient() {
},
});
}

export function handleError(e: unknown) {
if (e instanceof Error) {
if (isAxiosError(e)) {
core.error(formatAxiosError(e));
} else if (isAxiosError(e.cause)) {
core.error(formatAxiosError(e.cause));
} else {
core.error(e);
}
} else {
core.error(JSON.stringify(e));
}
core.setFailed("Error adding traceability to Jira issues");
}
3 changes: 3 additions & 0 deletions .github/scripts/jira/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,8 @@
"@types/node": "^20.14.10",
"typescript": "^5.5.3",
"vitest": "^2.0.3"
},
"peerDependencies": {
"axios": "^1.7.7"
}
}
11 changes: 7 additions & 4 deletions .github/scripts/jira/pnpm-lock.yaml

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

2 changes: 1 addition & 1 deletion .github/scripts/jira/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */

/* Language and Environment */
"target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"target": "ES2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
Expand Down

0 comments on commit bd62d0d

Please sign in to comment.