用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/autohandai/community-skills --skill error-handling-patterns命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | error-handling-patterns |
| description | Robust error handling patterns for TypeScript applications |
| license | MIT |
| compatibility | typescript 5+, nodejs 18+ |
| allowed-tools | read_file write_file apply_patch search_with_context |
// Base application error
export class AppError extends Error {
constructor(
message: string,
public readonly code: string,
public readonly statusCode: number = 500,
public readonly details?: unknown
) {
super(message);
this.name = this.constructor.name;
Error.captureStackTrace(this, this.constructor);
}
toJSON() {
return {
code: this.code,
message: this.message,
...(this.details && { details: this.details }),
};
}
}
// Specific error types
export class ValidationError extends AppError {
constructor(message: string, details?: Record<string, string>) {
super(message, 'VALIDATION_ERROR', 400, details);
}
}
export class NotFoundError extends AppError {
constructor(resource: string, id: string) {
super(`${resource} with id '${id}' not found`, 'NOT_FOUND', 404);
}
}
export class UnauthorizedError extends AppError {
constructor(message = 'Authentication required') {
super(message, 'UNAUTHORIZED', 401);
}
}
export class ForbiddenError extends AppError {
constructor(message = 'Insufficient permissions') {
super(message, 'FORBIDDEN', 403);
}
}
type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
// Helper functions
function ok<T>(data: T): Result<T, never> {
return { success: true, data };
}
function err<E>(error: E): Result<never, E> {
return { success: false, error };
}
// Usage
async function findUser(id: string): Promise<Result<User, NotFoundError>> {
const user = await db.users.findUnique({ where: { id } });
if (!user) {
return err(new NotFoundError('User', id));
}
return ok(user);
}
// Consuming
const result = await findUser('123');
(!result.) {
.(result..);
;
}
user = result.;
import { Component, ErrorInfo, ReactNode } from 'react';
interface Props {
children: ReactNode;
fallback?: ReactNode;
onError?: (error: Error, info: ErrorInfo) => void;
}
interface State {
hasError: boolean;
error: Error | null;
}
export class ErrorBoundary extends Component<Props, State> {
state: State = { hasError: false, error: null };
static getDerivedStateFromError(error: Error): State {
return { hasError: true, error };
}
componentDidCatch(error: Error, info: ErrorInfo) {
..?.(error, info);
}
() {
(..) {
.. ?? (
);
}
..;
}
}
// Wrapper for async functions
function tryCatch<T>(
promise: Promise<T>
): Promise<[null, T] | [Error, null]> {
return promise
.then((data) => [null, data] as [null, T])
.catch((error) => [error as Error, null]);
}
// Usage
const [error, user] = await tryCatch(fetchUser(id));
if (error) {
handleError(error);
return;
}
// user is guaranteed to be defined here
// Multiple operations
async function processOrder(orderId: string) {
const [orderError, order] = await tryCatch(getOrder(orderId));
if (orderError) return err(orderError);
const [paymentError] = await tryCatch(processPayment(order));
if (paymentError) {
await ((order));
(paymentError);
}
(order);
}
interface RetryOptions {
maxAttempts: number;
delayMs: number;
backoff?: 'linear' | 'exponential';
shouldRetry?: (error: Error) => boolean;
}
async function withRetry<T>(
fn: () => Promise<T>,
options: RetryOptions
): Promise<T> {
const { maxAttempts, delayMs, backoff = 'exponential', shouldRetry } = options;
let lastError: Error;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await fn();
} catch (error) {
lastError = error as Error;
if (shouldRetry && !shouldRetry(lastError)) {
throw lastError;
}
if (attempt < maxAttempts) {
const delay = backoff === 'exponential'
? delayMs * Math.pow(2, attempt - 1)
: delayMs * attempt;
await (delay);
}
}
}
lastError!;
}
data = ( (), {
: ,
: ,
: err..(),
});
import { z } from 'zod';
function validateInput<T>(schema: z.ZodSchema<T>, input: unknown): Result<T, ValidationError> {
const result = schema.safeParse(input);
if (!result.success) {
const details = result.error.flatten().fieldErrors;
return err(new ValidationError('Invalid input', details));
}
return ok(result.data);
}
// Usage
const userSchema = z.object({
email: z.string().email(),
age: z.number().min(18),
});
const result = validateInput(userSchema, req.body);
if (!result.success) {
return res.status(400).json(result.error.toJSON());
}
interface ErrorContext {
userId?: string;
requestId?: string;
path?: string;
[key: string]: unknown;
}
function logError(error: Error, context: ErrorContext = {}) {
const payload = {
timestamp: new Date().toISOString(),
name: error.name,
message: error.message,
stack: error.stack,
...(error instanceof AppError && { code: error.code }),
...context,
};
console.error(JSON.stringify(payload));
// Send to error tracking service
if (process.env.NODE_ENV === 'production') {
// Sentry.captureException(error, { extra: context });
}
}