Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import path from "path";
import yargs from "yargs";
import axios, { AxiosRequestConfig, AxiosResponse } from "axios";
import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from "axios";

import { ConfigLocator } from "./config";
import { ProfileStore, Profile } from "./profile-store";
Expand Down Expand Up @@ -244,8 +244,19 @@ async function runApiCommand(
...(hasBody ? { data: payload.data } : {}),
};

const response = await httpClient.request(requestConfig);
stdout(`${JSON.stringify(response.data, null, 2)}\n`);
try {
const response = await httpClient.request(requestConfig);
stdout(`${JSON.stringify(response.data, null, 2)}\n`);
} catch (err) {
if (err instanceof AxiosError && err.response?.data !== undefined) {
const body =
typeof err.response.data === "string"
? err.response.data
: JSON.stringify(err.response.data, null, 2);
throw new Error(`${err.message}\n${body}`);
}
throw err;
}
}

function parseBodyFlagValue(value: string): unknown {
Expand Down
29 changes: 29 additions & 0 deletions tests/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ConfigLocator } from "../src/config";
import { ProfileStore } from "../src/profile-store";
import { OpenapiLoader } from "../src/openapi-loader";
import { run, HttpClient } from "../src/cli";
import { AxiosError } from "axios";
import { VERSION } from "../src/version";

interface MemoryFsEntry {
Expand Down Expand Up @@ -750,6 +751,34 @@ describe("cli", () => {
).rejects.toThrow("Invalid JSON body value");
});

it("includes the response body in the error message on failed requests", async () => {
const { profileStore, openapiLoader } = createPostApiDeps();

const failingHttpClient: HttpClient = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
request: async (config: any) => {
const response = { status: 400, statusText: "Bad Request", headers: {}, config, data: { message: "invalid input" } };
throw new AxiosError("Request failed with status code 400", "ERR_BAD_REQUEST", config, {}, response);
},
};

await expect(
run(
[
"org_slug_repo_slug_ci_workflows_workflow_name_trigger",
"--org_slug", "myorg",
"--repo_slug", "myrepo",
"--workflow_name", "deploy",
"--input", '{"values":[{"name":"FOO","value":"bar"}]}',
],
{ cwd, profileStore, openapiLoader, httpClient: failingHttpClient, stdout: () => {} }
)
).rejects.toThrow(`Request failed with status code 400
{
"message": "invalid input"
}`);
});

it("builds JSON request body from declared OAS3 requestBody properties", async () => {
const localDir = `${cwd}/.ocli`;
const profilesPath = `${localDir}/profiles.ini`;
Expand Down
Loading