fix(openbao): include response body in error messages
Some checks failed
Some checks failed
Debugging the wizard migration flow, every OpenBao error was just `HTTP 403` with no context. The response body often carries the actual reason (missing capability, specific path, namespace mismatch), so surfacing it makes operator debugging a one-step task. Added a shared bodyText() helper that trims huge HTML error pages to 400 chars. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,17 @@
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import type { SecretBackendDriver, SecretData, ExternalRef, SecretRefResolver } from './types.js';
|
||||
|
||||
/** Best-effort read of a response body for error messages. Empty on parse failure. */
|
||||
async function bodyText(res: Response): Promise<string> {
|
||||
try {
|
||||
const text = await res.text();
|
||||
// Trim huge HTML error pages to the first 400 chars
|
||||
return text.length > 400 ? `${text.slice(0, 400)}…` : text;
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
export interface OpenBaoConfigBase {
|
||||
url: string;
|
||||
mount?: string;
|
||||
@@ -128,7 +139,7 @@ export class OpenBaoDriver implements SecretBackendDriver {
|
||||
if (res.status === 404) {
|
||||
throw new Error(`OpenBao: secret '${input.name}' not found at ${path}`);
|
||||
}
|
||||
if (!res.ok) throw new Error(`OpenBao read ${path}: HTTP ${res.status}`);
|
||||
if (!res.ok) throw new Error(`OpenBao read ${path}: HTTP ${res.status} ${await bodyText(res)}`);
|
||||
const body = await res.json() as { data?: { data?: SecretData } };
|
||||
return body.data?.data ?? {};
|
||||
}
|
||||
@@ -136,7 +147,7 @@ export class OpenBaoDriver implements SecretBackendDriver {
|
||||
async write(input: { name: string; data: SecretData }): Promise<{ externalRef: ExternalRef; storedData: SecretData }> {
|
||||
const path = this.pathFor(input.name);
|
||||
const res = await this.request('POST', `/v1/${this.mount}/data/${path}`, { data: input.data });
|
||||
if (!res.ok) throw new Error(`OpenBao write ${path}: HTTP ${res.status}`);
|
||||
if (!res.ok) throw new Error(`OpenBao write ${path}: HTTP ${res.status} ${await bodyText(res)}`);
|
||||
return { externalRef: `${this.mount}/${path}`, storedData: {} };
|
||||
}
|
||||
|
||||
@@ -144,7 +155,7 @@ export class OpenBaoDriver implements SecretBackendDriver {
|
||||
const path = this.pathFor(input.name);
|
||||
const res = await this.request('DELETE', `/v1/${this.mount}/metadata/${path}`);
|
||||
if (!res.ok && res.status !== 404) {
|
||||
throw new Error(`OpenBao delete ${path}: HTTP ${res.status}`);
|
||||
throw new Error(`OpenBao delete ${path}: HTTP ${res.status} ${await bodyText(res)}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +163,7 @@ export class OpenBaoDriver implements SecretBackendDriver {
|
||||
const listPath = this.pathPrefix === '' ? '' : `${this.pathPrefix}/`;
|
||||
const res = await this.request('LIST', `/v1/${this.mount}/metadata/${listPath}`);
|
||||
if (res.status === 404) return [];
|
||||
if (!res.ok) throw new Error(`OpenBao list: HTTP ${res.status}`);
|
||||
if (!res.ok) throw new Error(`OpenBao list: HTTP ${res.status} ${await bodyText(res)}`);
|
||||
const body = await res.json() as { data?: { keys?: string[] } };
|
||||
const keys = body.data?.keys ?? [];
|
||||
return keys
|
||||
|
||||
Reference in New Issue
Block a user