/**
* @fileoverview Error utilities for handling API errors
* This module provides utilities for classifying and handling errors.
*/
/**
* Possible error categories for API errors
* @enum {string}
*/
// This enum is part of the public API and is used by consumers, even if not all values are used in this file
export enum ErrorCategory {
/** Error related to authentication or authorization */
AUTH = 'AUTH',
/** Error with network connectivity */
NETWORK = 'NETWORK',
/** Error with server processing */
SERVER = 'SERVER',
/** Error with client input */
CLIENT = 'CLIENT',
/** Error with request timing out */
TIMEOUT = 'TIMEOUT',
/** Error with rate limiting */
RATE_LIMIT = 'RATE_LIMIT',
/** Error with the GraphQL schema */
SCHEMA = 'SCHEMA',
/** Error with data not found */
NOT_FOUND = 'NOT_FOUND',
/** Error with data formatting */
FORMAT = 'FORMAT',
/** Other uncategorized errors */
OTHER = 'OTHER',
}
/**
* Enriched error with additional metadata
* Extends the standard Error with additional properties for better error handling.
* @interface
*/
export interface ClassifiedError extends Error {
/** The category of the error */
category: ErrorCategory;
/** The original error that caused this error */
originalError?: unknown;
/** Any additional metadata related to the error */
metadata?: Record<string, unknown>;
}
/**
* Create a new classified error with additional metadata
* @param message The error message
* @param category The error category
* @param originalError The original error that caused this error, useful for debugging and error tracing
* @param metadata Additional contextual information about the error as key-value pairs
* @returns A new classified error with the specified properties
* @example
* const error = createClassifiedError(
* 'Failed to fetch project data',
* ErrorCategory.NETWORK,
* originalError,
* { projectId: '123', endpoint: '/api/projects' }
* );
*/
export function createClassifiedError(
message: string,
category: ErrorCategory,
originalError?: unknown,
metadata?: Record<string, unknown>
): ClassifiedError {
const error = new Error(message) as ClassifiedError;
error.category = category;
error.originalError = originalError;
if (metadata !== undefined) {
error.metadata = metadata;
}
return error;
}
/**
* Check if an error is a classified error
* @param error The error to check
* @returns True if the error is a classified error
*/
export function isClassifiedError(error: unknown): error is ClassifiedError {
return Boolean(
error &&
typeof error === 'object' &&
'message' in error &&
'category' in error &&
typeof (error as Record<string, unknown>).category === 'string'
);
}
/**
* Error classifier for GraphQL errors
* @param error The error to classify
* @returns The classified error category
*/
export function classifyGraphQLError(error: Error): ErrorCategory {
const message = error.message.toLowerCase();
// Define error patterns and their corresponding categories
const errorPatterns: Record<ErrorCategory, string[]> = {
[ErrorCategory.AUTH]: [
'authentication',
'unauthorized',
'access denied',
'not authorized',
'forbidden',
'token',
'api key',
],
[ErrorCategory.RATE_LIMIT]: ['rate limit', 'too many requests', 'throttled'],
[ErrorCategory.NETWORK]: ['network', 'connection', 'econnreset', 'econnrefused'],
[ErrorCategory.TIMEOUT]: ['timeout', 'timed out', 'etimedout'],
[ErrorCategory.SCHEMA]: [
'cannot query field',
'unknown argument',
'unknown type',
'field not defined',
],
[ErrorCategory.NOT_FOUND]: ['not found', 'nonetype', 'does not exist'],
[ErrorCategory.SERVER]: ['server error', 'internal error', '500'],
[ErrorCategory.CLIENT]: [],
[ErrorCategory.FORMAT]: [],
[ErrorCategory.OTHER]: [],
};
// Check each category's patterns
for (const [category, patterns] of Object.entries(errorPatterns)) {
if (patterns.some((pattern) => message.includes(pattern))) {
return category as ErrorCategory;
}
}
// Default to OTHER
return ErrorCategory.OTHER;
}
// This code helps document the intended use of the enum values
// Each category has a specific use case in the error handling flow
// For example:
// - AUTH errors are for authentication-related failures
// - NETWORK errors happen when network connectivity is lost
// - etc.