error-handling
3
总安装量
1
周安装量
#57072
全站排名
安装命令
npx skills add https://github.com/dseirz-rgb/worker --skill error-handling
Agent 安装分布
amp
1
opencode
1
cursor
1
kimi-cli
1
codex
1
github-copilot
1
Skill 文档
Error Handling (é误å¤ç)
ð¡ï¸ æ ¸å¿ç念: é误æ¯ç¨åºçä¸é¨åï¼ä¼é å°å¤çé误æ¯é¿å é误æ´éè¦ã
ð´ 第ä¸ååï¼æ°¸ä¸å´©æºï¼ä¼é é级
ä»»ä½é误é½ä¸åºè¯¥å¯¼è´æ´ä¸ªåºç¨å´©æºï¼
â é误æè·¯: "è¿ä¸ªé误ä¸åºè¯¥åçï¼ç´æ¥ throw"
â
æ£ç¡®æè·¯: "è¿ä¸ªé误å¯è½åçï¼åå¤å¥½éçº§æ¹æ¡"
â é误æè·¯: "ç¨æ·çå°é误信æ¯å°±ç¥éæä¹åäº"
â
æ£ç¡®æè·¯: "ç¨æ·éè¦æç¡®çæå¼å坿ä½ç建议"
å¤çä¼å 级: é¢é² > æè· > é级 > éç¥ç¨æ·
When to Use This Skill
ä½¿ç¨æ¤æè½å½ä½ éè¦ï¼
- 设计é误å¤çæ¶æ
- å®ç°éè¯é»è¾ï¼ææ°éé¿ï¼
- ç¼åç¨æ·å好çéè¯¯æ¶æ¯
- å®ç°ä¼é é级çç¥
- è®¾è®¡ç»æåæ¥å¿æ ¼å¼
- å¤ç API è°ç¨å¤±è´¥
Not For / Boundaries
æ¤æè½ä¸éç¨äºï¼
- ä¸å¡é»è¾éªè¯ï¼ä½¿ç¨è¡¨åéªè¯ï¼
- ç±»åæ£æ¥ï¼ä½¿ç¨ TypeScriptï¼
- å®å ¨æ¼æ´å¤çï¼ä½¿ç¨å®å ¨å®¡è®¡ï¼
Quick Reference
ð¯ é误å¤çå³çæµç¨
é误åç â åç±»è¯å« â 坿¢å¤? â éè¯/é级 â è®°å½æ¥å¿
â
ä¸å¯æ¢å¤ â å好æç¤º â è®°å½æ¥å¿ â 䏿¥çæ§
ð é误å¤çæ£æ¥æ¸ å
| æ£æ¥é¡¹ | ç®ç |
|---|---|
| 1. é误æ¯å¦è¢«æ£ç¡®åç±»ï¼ | ç¡®å®å¤ççç¥ |
| 2. æ¯å¦éè¦éè¯ï¼ | ä¸´æ¶æ§é误å¯éè¯ |
| 3. ææ²¡æéçº§æ¹æ¡ï¼ | ä¿è¯åºæ¬åè½å¯ç¨ |
| 4. ç¨æ·æ¶æ¯æ¯å¦åå¥½ï¼ | é¿å ææ¯æ¯è¯ |
| 5. æ¥å¿æ¯å¦å®æ´ï¼ | 便äºé®é¢ææ¥ |
| 6. æ¯å¦éè¦ä¸æ¥ï¼ | 严éé误éè¦åè¦ |
ð é误åç±»ä½ç³»
| ç±»å | ç¤ºä¾ | æ¯å¦éè¯ | å¤çæ¹å¼ |
|---|---|---|---|
| ç½ç»é误 | è¿æ¥è¶ æ¶ãDNS 失败 | â | ææ°éé¿éè¯ |
| 认è¯é误 | Token è¿æãæªææ | â | å·æ° Token æéæ°ç»å½ |
| æéé误 | æ è®¿é®æé | â | æç¤ºç¨æ·è系管çå |
| éªè¯é误 | åæ°æ ¼å¼é误 | â | æ¾ç¤ºå ·ä½å段é误 |
| éæµé误 | 请æ±è¿äºé¢ç¹ | â | çå¾ Retry-After åéè¯ |
| æå¡å¨é误 | 500ã503 | â | éè¯ + é级 |
| ä¸å¡é误 | ä½é¢ä¸è¶³ãåºåä¸è¶³ | â | æ¾ç¤ºä¸å¡æç¤º |
â é误å¤çæä½³å®è·µ
// â
æ£ç¡®ï¼åå±å¤çï¼ä¼é
é级
try {
return await primaryService.fetch();
} catch (error) {
if (isRetryable(error)) {
return await withRetry(() => primaryService.fetch());
}
if (hasFallback) {
return await fallbackService.fetch();
}
logError(error);
throw new UserFriendlyError('æå¡ææ¶ä¸å¯ç¨ï¼è¯·ç¨åéè¯');
}
// â é误ï¼ç´æ¥æåºåå§é误
try {
return await service.fetch();
} catch (error) {
throw error; // ç¨æ·çå° "TypeError: Cannot read property..."
}
ð« ç¦æ¢è¡ä¸º
| â ç¦æ¢ | â æ£ç¡® |
|---|---|
| åæé误ä¸å¤ç | è³å°è®°å½æ¥å¿ |
| æ¾ç¤ºææ¯éè¯¯ä¿¡æ¯ | æ¾ç¤ºç¨æ·åå¥½æ¶æ¯ |
| ææé误é½éè¯ | åªéè¯ä¸´æ¶æ§é误 |
| æ ééè¯ | 设置æå¤§éè¯æ¬¡æ° |
| ç«å³éè¯ | ä½¿ç¨ææ°éé¿ |
| 忽ç¥é误ä¸ä¸æ | ä¿çé误é¾åå æ |
é误å¤ç工使µ
Phase 1: é误æè·
// 1. ä½¿ç¨ try-catch æè·åæ¥é误
try {
riskyOperation();
} catch (error) {
handleError(error);
}
// 2. ä½¿ç¨ .catch() æè·å¼æ¥é误
asyncOperation()
.catch(handleError);
// 3. 使ç¨å
¨å±é误å¤çå¨
window.addEventListener('unhandledrejection', (event) => {
handleError(event.reason);
});
Phase 2: é误åç±»
function classifyError(error: unknown): ErrorCategory {
if (error instanceof NetworkError) return 'network';
if (error instanceof AuthError) return 'auth';
if (error instanceof ValidationError) return 'validation';
if (error instanceof RateLimitError) return 'rate_limit';
if (error instanceof ServerError) return 'server';
return 'unknown';
}
Phase 3: é误å¤ç
async function handleError(error: unknown): Promise<void> {
const category = classifyError(error);
switch (category) {
case 'network':
await handleNetworkError(error);
break;
case 'auth':
await handleAuthError(error);
break;
case 'rate_limit':
await handleRateLimitError(error);
break;
default:
await handleUnknownError(error);
}
}
Phase 4: ç¨æ·éç¥
function notifyUser(error: AppError): void {
const message = getLocalizedMessage(error);
const action = getSuggestedAction(error);
toast.error(message, {
action: action ? {
label: action.label,
onClick: action.handler,
} : undefined,
});
}
Examples
Example 1: API è°ç¨é误å¤ç
Input: “éè¦è°ç¨å¤é¨ APIï¼å¯è½ä¼å¤±è´¥”
Steps:
- è¯å«å¯è½çé误类å
- å®ç°éè¯é»è¾
- åå¤éçº§æ¹æ¡
- ç¼åç¨æ·åå¥½æ¶æ¯
Expected Output:
async function fetchUserData(userId: string): Promise<User> {
try {
return await withRetry(
() => api.users.get(userId),
{
maxRetries: 3,
baseDelay: 1000,
retryCondition: isRetryableError,
}
);
} catch (error) {
// é级ï¼è¿åç¼åæ°æ®
const cached = await cache.get(`user:${userId}`);
if (cached) {
logWarning('使ç¨ç¼åæ°æ®', { userId, error });
return cached;
}
// æ æ³éçº§ï¼æåºç¨æ·å好é误
throw new UserFriendlyError(
'æ æ³è·åç¨æ·ä¿¡æ¯ï¼è¯·æ£æ¥ç½ç»è¿æ¥åéè¯',
{ cause: error }
);
}
}
Example 2: 表åæäº¤é误å¤ç
Input: “表åæäº¤å¯è½è¿åéªè¯é误”
Expected Output:
async function submitForm(data: FormData): Promise<Result> {
try {
return await api.submit(data);
} catch (error) {
if (error instanceof ValidationError) {
// æ¾ç¤ºå段级é误
return {
success: false,
fieldErrors: error.fieldErrors,
};
}
if (error instanceof ConflictError) {
return {
success: false,
message: 'æ°æ®å·²è¢«ä¿®æ¹ï¼è¯·å·æ°åéè¯',
};
}
// å
¶ä»é误
logError('表åæäº¤å¤±è´¥', error);
return {
success: false,
message: 'æäº¤å¤±è´¥ï¼è¯·ç¨åéè¯',
};
}
}
Example 3: æ¹éæä½é误å¤ç
Input: “æ¹éå¤çå¤ä¸ªé¡¹ç®ï¼é¨åå¯è½å¤±è´¥”
Expected Output:
async function batchProcess<T>(
items: T[],
processor: (item: T) => Promise<void>
): Promise<BatchResult> {
const results = await Promise.allSettled(
items.map(item => processor(item))
);
const succeeded = results.filter(r => r.status === 'fulfilled');
const failed = results.filter(r => r.status === 'rejected');
if (failed.length > 0) {
logWarning('æ¹éå¤çé¨å失败', {
total: items.length,
succeeded: succeeded.length,
failed: failed.length,
errors: failed.map(r => (r as PromiseRejectedResult).reason),
});
}
return {
total: items.length,
succeeded: succeeded.length,
failed: failed.length,
message: failed.length > 0
? `å¤ç宿ï¼${failed.length} 项失败`
: 'å
¨é¨å¤çæå',
};
}
References
references/graceful-degradation.md: ä¼é é级模å¼references/retry-patterns.md: éè¯é»è¾æ¨¡æ¿ï¼ææ°éé¿ï¼references/message-templates.md: 䏿éè¯¯æ¶æ¯æ¨¡æ¿ãç»æåæ¥å¿æ ¼å¼
Maintenance
- Sources: é¡¹ç®æä½³å®è·µ, 社åºç»éªæ»ç»
- Last Updated: 2025-01-01
- Known Limits:
- é误åç±»éæ ¹æ®å ·ä½ä¸å¡è°æ´
- éè¯çç¥éèèå¹çæ§