From 8815c1596c8a33988678d50cf30db764940cc20e Mon Sep 17 00:00:00 2001 From: chenbaowang <49091147+Rsweater@users.noreply.github.com> Date: Tue, 21 Apr 2026 10:19:38 +0800 Subject: [PATCH] fix(cli): human-readable API error messages ApiError previously displayed raw JSON like: API error 403: {"code":403,"msg":"Access denied..."} Now extracts the msg field from the API response body and displays: Access denied to skill: find-skills Run `skillhub login` to authenticate. Changes: - Add extractHumanMessage() to pull msg/message/error from response - ApiError.message now shows human text instead of raw JSON - 401/403 responses append login hint - whoami: remove redundant 'Not authenticated:' prefix --- skillhub-cli/src/commands/whoami.ts | 2 +- skillhub-cli/src/core/api-client.ts | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/skillhub-cli/src/commands/whoami.ts b/skillhub-cli/src/commands/whoami.ts index dbb77ad28..936026089 100644 --- a/skillhub-cli/src/commands/whoami.ts +++ b/skillhub-cli/src/commands/whoami.ts @@ -23,7 +23,7 @@ export function registerWhoami(program: Command) { console.log(`Display Name: ${resp.user.displayName}`); } } catch (e: any) { - error(`Not authenticated: ${e.message}`); + error(e.message); process.exit(1); } }); diff --git a/skillhub-cli/src/core/api-client.ts b/skillhub-cli/src/core/api-client.ts index d87a01426..bf94edc95 100644 --- a/skillhub-cli/src/core/api-client.ts +++ b/skillhub-cli/src/core/api-client.ts @@ -121,11 +121,31 @@ export class ApiClient { } } +function extractHumanMessage(body: unknown): string | null { + if (typeof body !== "object" || body === null) return null; + + const b = body as Record; + + // Native API: { code, msg, data } — "msg" is authoritative + if (typeof b.msg === "string" && b.msg.length > 0) return b.msg; + if (typeof b.message === "string" && b.message.length > 0) return b.message; + if (typeof b.error === "string" && b.error.length > 0) return b.error; + + return null; +} + export class ApiError extends Error { constructor( public statusCode: number, public body: unknown, ) { - super(`API error ${statusCode}: ${JSON.stringify(body)}`); + const msg = extractHumanMessage(body); + let detail = msg ?? `HTTP ${statusCode}`; + + if (statusCode === 401 || statusCode === 403) { + detail += "\nRun `skillhub login` to authenticate."; + } + + super(detail); } }