Skip to content

Commit 3d734c3

Browse files
author
A.P.A.Slaa
committed
fix: better error handling and parsing
1 parent fd2e86a commit 3d734c3

1 file changed

Lines changed: 43 additions & 13 deletions

File tree

src/index.ts

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,48 @@ export namespace OpenPolicyAgent {
233233
get(pretty?: boolean): Promise<GetStatusResponse>
234234
}
235235

236+
export type OPAError = {
237+
readonly code: string,
238+
readonly message: string,
239+
readonly location: { file: string, row: number, col: number }
240+
readonly details: { line: string, idx: number }
241+
}
242+
243+
export class ClientError extends Error {
244+
245+
246+
constructor(public readonly code: string, message: string, public readonly errors: OPAError[], public readonly response: Response) {
247+
super(message);
248+
}
249+
250+
toString() {
251+
return JSON.stringify({
252+
code: this.code,
253+
message: this.message,
254+
errors: this.errors
255+
})
256+
}
257+
258+
static async fromResponse(response: Response){
259+
let code: string = 'unknown';
260+
let message = `OPA request failed: ${response.status} ${response.statusText}`;
261+
let errors: OPAError[] = [];
262+
try {
263+
const bodyText = await response.text();
264+
if (bodyText) {
265+
const resp_body = JSON.parse(bodyText);
266+
if ('code' in resp_body && resp_body.code) code = resp_body.code;
267+
if ('message' in resp_body && resp_body.message) message = resp_body.message;
268+
if ('errors' in resp_body && resp_body.errors) code = resp_body.errors;
269+
}
270+
} catch {
271+
// Ignore
272+
}
273+
return new ClientError(code, message,errors, response);;
274+
}
275+
276+
}
277+
236278
/**
237279
* A lightweight TypeScript client for the Open Policy Agent (OPA) REST API.
238280
* Uses the native `fetch` API and requires no external dependencies.
@@ -324,19 +366,7 @@ export namespace OpenPolicyAgent {
324366
});
325367

326368
if (!response.ok) {
327-
let message = `OPA request failed: ${response.status} ${response.statusText}`;
328-
let cause: any;
329-
try {
330-
const bodyText = await response.text();
331-
if (bodyText) {
332-
cause = JSON.parse(bodyText);
333-
if (cause.message) message += ` - ${cause.message}`;
334-
}
335-
} catch {
336-
// Ignore
337-
}
338-
// @ts-ignore
339-
throw new Error(message, {cause});
369+
throw await ClientError.fromResponse(response);
340370
}
341371

342372
const text = await response.text();

0 commit comments

Comments
 (0)