Skip to content

Commit adaa8ae

Browse files
feat: surface API 401 error message with login suggestion in portal generation
Previously, running portal commands while logged out showed the generic "An unexpected error occurred" message because the SDK's typed 401 error (UnauthorizedResponseError) was not recognized by the axios-only handleServiceError. Handle ApiError with status 401 in generatePortal, extract the API's message, and pair it with a suggestion to run `apimatic auth login` or pass `--auth-key`. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 5d50968 commit adaa8ae

2 files changed

Lines changed: 16 additions & 2 deletions

File tree

src/infrastructure/service-error.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ export class ServiceError {
3030
static notFound(customMessage: string): ServiceError {
3131
return new ServiceError(ServiceErrorCode.NotFound, customMessage, {});
3232
}
33+
static unauthorized(apiMessage: string | null): ServiceError {
34+
const message = `${apiMessage ?? "You are not authorized to perform this action."} Please run ${f.cmdAlt(
35+
"apimatic",
36+
"auth",
37+
"login"
38+
)} to log in, or provide a valid auth key using the ${f.flag("auth-key")} flag.`;
39+
return new ServiceError(ServiceErrorCode.UnAuthorized, message, {});
40+
}
3341

3442
static readonly values: ServiceError[] = [
3543
ServiceError.NotFound,

src/infrastructure/services/portal-service.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,16 @@ export class PortalService {
7474
if (error.statusCode === 400) {
7575
return err(ServiceError.badRequest(errorMessage, errors));
7676
}
77-
if (error.statusCode === 403) {
78-
return err(ServiceError.forbidden(errorMessage));
77+
if (error.statusCode === 401) {
78+
return err(ServiceError.UnAuthorized);
7979
}
8080
}
81+
if (error instanceof ApiError && error.statusCode === 401) {
82+
// The API reports the reason as {"message": "..."} which the SDK
83+
// deserializes into `result` for its typed 401 error.
84+
const apiMessage = (error.result as { message?: string } | undefined)?.message ?? null;
85+
return err(ServiceError.unauthorized(apiMessage));
86+
}
8187
const serviceError = handleServiceError(error);
8288
return err(serviceError);
8389
} finally {

0 commit comments

Comments
 (0)