wrongmove/crawler/frontend/src/auth/errors.ts

60 lines
1.9 KiB
TypeScript

export enum AuthErrorType {
REDIRECT_FAILED = 'REDIRECT_FAILED',
CALLBACK_FAILED = 'CALLBACK_FAILED',
NETWORK_ERROR = 'NETWORK_ERROR',
USER_CANCELLED = 'USER_CANCELLED',
}
export interface AuthError {
type: AuthErrorType;
message: string;
retryable: boolean;
}
export function parseOidcError(error: unknown): AuthError {
const errorMessage = error instanceof Error ? error.message : String(error);
const errorString = errorMessage.toLowerCase();
// Check for popup/redirect blocked errors
if (errorString.includes('popup') || errorString.includes('blocked') || errorString.includes('window')) {
return {
type: AuthErrorType.REDIRECT_FAILED,
message: 'Unable to redirect. Please check if popups are blocked.',
retryable: true,
};
}
// Check for user cancellation
if (errorString.includes('cancel') || errorString.includes('closed') || errorString.includes('denied')) {
return {
type: AuthErrorType.USER_CANCELLED,
message: 'Sign in was cancelled.',
retryable: true,
};
}
// Check for network errors
if (errorString.includes('network') || errorString.includes('fetch') || errorString.includes('timeout') || errorString.includes('failed to fetch')) {
return {
type: AuthErrorType.NETWORK_ERROR,
message: 'Unable to reach authentication server. Please check your connection.',
retryable: true,
};
}
// Check for callback/state errors
if (errorString.includes('state') || errorString.includes('invalid') || errorString.includes('mismatch') || errorString.includes('no matching state')) {
return {
type: AuthErrorType.CALLBACK_FAILED,
message: 'Login verification failed. Please try again.',
retryable: true,
};
}
// Default error
return {
type: AuthErrorType.CALLBACK_FAILED,
message: errorMessage || 'An unexpected error occurred during sign in.',
retryable: true,
};
}