@@ -2,11 +2,11 @@ import { createHash } from 'crypto'
22
33import { getCiEnv } from '@codebuff/common/env-ci'
44import {
5- AuthenticationError ,
6- ErrorCodes ,
75 getUserInfoFromApiKey as defaultGetUserInfoFromApiKey ,
8- NetworkError ,
9- RETRYABLE_ERROR_CODES ,
6+ isRetryableStatusCode ,
7+ getErrorStatusCode ,
8+ createAuthError ,
9+ createServerError ,
1010 MAX_RETRIES_PER_MESSAGE ,
1111 RETRY_BACKOFF_BASE_DELAY_MS ,
1212} from '@codebuff/sdk'
@@ -47,6 +47,14 @@ type ValidatedUserInfo = {
4747 email : string
4848}
4949
50+ /**
51+ * Check if an error is an authentication error (401, 403)
52+ */
53+ function isAuthenticationError ( error : unknown ) : boolean {
54+ const statusCode = getErrorStatusCode ( error )
55+ return statusCode === 401 || statusCode === 403
56+ }
57+
5058/**
5159 * Validates an API key by calling the backend
5260 *
@@ -69,42 +77,39 @@ export async function validateApiKey({
6977
7078 if ( ! authResult ) {
7179 logger . error ( '❌ API key validation failed - invalid credentials' )
72- throw new AuthenticationError ( 'Invalid API key' , 401 )
80+ throw createAuthError ( 'Invalid API key' )
7381 }
7482
7583 return authResult
7684 } catch ( error ) {
77- if ( error instanceof AuthenticationError ) {
85+ const statusCode = getErrorStatusCode ( error )
86+
87+ if ( isAuthenticationError ( error ) ) {
7888 logger . error ( '❌ API key validation failed - authentication error' )
79- // Rethrow the original error to preserve error type for higher layers
89+ // Rethrow the original error to preserve statusCode for higher layers
8090 throw error
8191 }
8292
83- if ( error instanceof NetworkError ) {
93+ if ( statusCode !== undefined && isRetryableStatusCode ( statusCode ) ) {
8494 logger . error (
8595 {
86- error : error . message ,
87- code : error . code ,
96+ error : error instanceof Error ? error . message : String ( error ) ,
97+ statusCode ,
8898 } ,
8999 '❌ API key validation failed - network error' ,
90100 )
91- // Rethrow the original error to preserve error type for higher layers
101+ // Rethrow the original error to preserve statusCode for higher layers
92102 throw error
93103 }
94104
95- // Unknown error - wrap in NetworkError for consistency
105+ // Unknown error - wrap with statusCode for consistency
96106 logger . error (
97107 {
98108 error : error instanceof Error ? error . message : String ( error ) ,
99109 } ,
100110 '❌ API key validation failed - unknown error' ,
101111 )
102- throw new NetworkError (
103- 'Authentication failed' ,
104- ErrorCodes . UNKNOWN_ERROR ,
105- undefined ,
106- error ,
107- )
112+ throw createServerError ( 'Authentication failed' )
108113 }
109114}
110115
@@ -139,12 +144,13 @@ export function useAuthQuery(deps: UseAuthQueryDeps = {}) {
139144 // Retry only for retryable network errors (5xx, timeouts, etc.)
140145 // Don't retry authentication errors (invalid credentials)
141146 retry : ( failureCount , error ) => {
147+ const statusCode = getErrorStatusCode ( error )
142148 // Don't retry authentication errors - user needs to update credentials
143- if ( error instanceof AuthenticationError ) {
149+ if ( isAuthenticationError ( error ) ) {
144150 return false
145151 }
146152 // Retry network errors if they're retryable and we haven't exceeded max retries
147- if ( error instanceof NetworkError && RETRYABLE_ERROR_CODES . has ( error . code ) ) {
153+ if ( statusCode !== undefined && isRetryableStatusCode ( statusCode ) ) {
148154 return failureCount < MAX_RETRIES_PER_MESSAGE
149155 }
150156 // Don't retry other errors
0 commit comments