@podx/core
Version:
🚀 Core utilities and shared functionality for PODx - Advanced Twitter/X scraping and crypto analysis toolkit
140 lines (137 loc) • 4.89 kB
JavaScript
// src/errors/index.ts
function createError(type, message, context, originalError) {
const statusCodes = {
AUTHENTICATION: 401,
AUTHORIZATION: 403,
VALIDATION: 400,
CONFIGURATION: 500,
API: 502,
FILESYSTEM: 500,
NETWORK: 503,
DATABASE: 500,
RATE_LIMIT: 429,
UNKNOWN: 500
};
const base = {
type,
message,
statusCode: statusCodes[type]
};
if (context !== undefined) {
base.context = context;
}
if (originalError !== undefined) {
base.originalError = originalError;
}
return base;
}
var ValidationError = (message, context) => createError("VALIDATION", message, context);
var errors = {
authentication: (message = "Authentication failed", context) => createError("AUTHENTICATION", message, context),
authorization: (message = "Authorization failed", context) => createError("AUTHORIZATION", message, context),
validation: (message = "Validation failed", context) => createError("VALIDATION", message, context),
configuration: (message = "Configuration error", context) => createError("CONFIGURATION", message, context),
api: (message = "API error", context) => createError("API", message, context),
filesystem: (message = "File system error", context) => createError("FILESYSTEM", message, context),
network: (message = "Network error", context) => createError("NETWORK", message, context),
database: (message = "Database error", context) => createError("DATABASE", message, context),
rateLimit: (message = "Rate limit exceeded", retryAfter, context) => {
const base = createError("RATE_LIMIT", message, context);
if (retryAfter !== undefined)
base.retryAfter = retryAfter;
return base;
},
unknown: (message = "Unknown error occurred", originalError, context) => createError("UNKNOWN", message, context, originalError)
};
class ErrorHandler {
static async withErrorHandling(operation, context) {
try {
return await operation();
} catch (error) {
if (this.isXServeError(error)) {
throw error;
}
const wrappedError = createError("UNKNOWN", error instanceof Error ? error.message : "Unknown error occurred", { ...context, originalError: error }, error instanceof Error ? error : undefined);
throw wrappedError;
}
}
static async safeExecute(operation, context) {
try {
const data = await operation();
return { success: true, data };
} catch (error) {
const xserveError = this.isXServeError(error) ? error : createError("UNKNOWN", error instanceof Error ? error.message : "Unknown error occurred", { ...context, originalError: error }, error instanceof Error ? error : undefined);
return { success: false, error: xserveError };
}
}
static isRetryable(error) {
if (this.isXServeError(error)) {
return ["NETWORK", "API", "RATE_LIMIT"].includes(error.type);
}
const retryableMessages = [
"timeout",
"network",
"connection",
"ECONNRESET",
"ENOTFOUND",
"ECONNREFUSED"
];
const message = error.message.toLowerCase();
return retryableMessages.some((pattern) => message.includes(pattern));
}
static getUserMessage(error) {
if (this.isXServeError(error)) {
switch (error.type) {
case "AUTHENTICATION":
return "Authentication failed. Please check your credentials.";
case "AUTHORIZATION":
return "You do not have permission to perform this action.";
case "VALIDATION":
return "Invalid input provided. Please check your data.";
case "RATE_LIMIT":
return "Rate limit exceeded. Please try again later.";
case "CONFIGURATION":
return "Configuration error. Please check your settings.";
case "NETWORK":
return "Network error. Please check your connection.";
default:
return "An unexpected error occurred. Please try again.";
}
}
return "An unexpected error occurred. Please try again.";
}
static isXServeError(error) {
return error && typeof error === "object" && "type" in error && "message" in error;
}
}
class RetryHandler {
static async withRetry(operation, options = {}) {
const {
maxRetries = 3,
baseDelay = 1000,
maxDelay = 30000,
shouldRetry = ErrorHandler.isRetryable
} = options;
let lastError;
for (let attempt = 0;attempt <= maxRetries; attempt++) {
try {
return await operation();
} catch (error) {
lastError = error;
if (attempt === maxRetries || !shouldRetry(error)) {
throw lastError;
}
const delay = Math.min(baseDelay * Math.pow(2, attempt), maxDelay);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
throw lastError;
}
}
export {
errors,
createError,
ValidationError,
RetryHandler,
ErrorHandler
};