Skills Plugins MCP Prompt Model 博客 我的中心
开发编程 #python #typescript #design #ai

error-handling

Patterns for robust error handling across TypeScript, Python, and Go. Covers typed errors, error boundaries, retries, circuit breakers, and user-facing error messages. Use when designing error types, retries, circuit breakers, or user-facing failure messages in TypeScript, Python, or Go.

DeepseekModel 官方收录技能 质量 优秀 · 90 v1.0.0

获取

https://deepseekmodel.com/api/download.php?id=affaan-m-ecc-skills-error-handling-skill-md&format=skill
下载 .skill 标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用
.skill 文件中 system_prompt 字段的实际内容。
name error-handling description Patterns for robust error handling across TypeScript, Python, and Go. Covers typed errors, error boundaries, retries, circuit breakers, and user-facing error messages. Use when designing error types, retries, circuit breakers, or user-facing failure messages in TypeScript, Python, or Go. metadata {"origin":"ECC"} Error Handling Patterns Consistent, robust error handling patterns for production applications. When to Activate Designing error types or exception hierarchies for a new module or service Adding retry logic or circuit breakers for unreliable external dependencies Reviewing API endpoints for missing error handling Implementing user-facing error messages and feedback Debugging cascading failures or silent error swallowing Core Principles Fail fast and loudly — surface errors at the boundary where they occur; don't bury them Typed errors over string messages — errors are first-class values with structure User messages ≠ developer messages — show friendly text to users, log full context server-side Never swallow errors silently — every catch block must either handle, re-throw, or log Errors are part of your API contract — document every error code a client may receive TypeScript / JavaScript Typed Error Classes // Define an error hierarchy for your domain 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 // Maintain correct prototype chain in transpiled ES5 JavaScript. // Required for `instanceof` checks (e.g., `error instanceof NotFoundError`) // to work correctly when extending the built-in Error class. Object . setPrototypeOf ( this , new . target . prototype ) } } export class NotFoundError extends AppError { constructor ( resource : string , id : string ) { super ( ` ${resource} not found: ${id} ` , 'NOT_FOUND' , 404 ) } } export class ValidationError extends AppError { constructor ( message : string , details : { field: string ; message: string }[] ) { super (message, 'VALIDATION_ERROR' , 422 , details) } } export class UnauthorizedError extends AppError { constructor ( reason = 'Authentication required' ) { super (reason, 'UNAUTHORIZED' , 401 ) } } export class RateLimitError extends AppError { constructor ( public readonly retryAfterMs : number ) { super ( 'Rate limit exceeded' , 'RATE_LIMITED' , 429 ) } } Result Pattern (no-throw style) For operations where failure is expected and common (parsing, external calls): type Result <T, E = AppError > = | { ok : true ; value : T } | { ok : false ; error : E } function ok<T>( value : T): Result <T> { return { ok : true , value } } function err<E>( error : E): Result < never , E> { return { ok : false , error } } // Usage async function fetchUser ( id : string ): Promise < Result < User >> { try { const user = await db. users . findUnique ({ where : { id } }) if (!user) return err ( new NotFoundError ( 'User' , id)) return ok (user) } catch (e) { return err ( new AppError ( 'Database error' , 'DB_ERROR' )) } } const result = await fetchUser ( 'abc-123' ) if (!result. ok ) { // TypeScript knows result.error here logger. error ( 'Failed to fetch user' , { error : result. error }) return } // TypeScript knows result.value here console . log (result. value . email ) API Error Handler (Next.js / Express) import { NextRequest , NextResponse } from 'next/server' function handleApiError ( error : unknown ): NextResponse { // Known application error if (error instanceof AppError ) { return NextResponse . json ( { error : { code : error. code , message : error. message , ...(error. details ? { details : error. details } : {}), }, }, { status : error. statusCode }, ) } // Zod validation error if (error instanceof z. ZodError ) { return NextResponse . json ( { error : { code : 'VALIDATION_ERROR' , message : 'Request validation failed' , details : error. issues . map ( i => ({ field : i. path . join ( '.' ), message : i. message , })), }, }, { status : 422 }, ) } // Unexpected error — log details, return generic message console . error ( 'Unexpected error:' , error) return NextResponse . json ( { error : { code : 'INTERNAL_ERROR' , message : 'An unexpected error occurred' } }, { status : 500 }, ) } export async function POST ( req : NextRequest ) { try { // ... handler logic } catch (error) { return handleApiError (error) } } React Error Boundary import { Component , ErrorInfo , ReactNode } from 'react' interface Props { fallback : ReactNode onError ?: ( error : Error , info : ErrorInfo ) => void children : ReactNode } 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 ) { this . props . onError ?.(error, info) console . error ( 'Unhandled React error:' , error, info) } render ( ) { if ( this . state . hasError ) return this . props . fallback return this . props . children } } // Usage < ErrorBoundary fallback={ < p > Something went wrong. Please refresh. </ p > }> < MyComponent /> </ ErrorBoundary > Python Custom Exception Hierarchy class AppError ( Exception ): """Base application error.""" def __init__ ( self, message: str , code: str , status_code: int = 500 ): super ().__init__(message) self .code = code self .status_code = status_code class NotFoundError ( AppError ): def __init__ ( self, resource: str , id : str ): super ().__init__( f" {resource} not found: { id } " , "NOT_FOUND" , 404 ) class ValidationError ( AppError ): def __init__ ( self, message: str , details: list [ dict ] | None = None ): super ().__init__(message, "VALIDATION_ERROR" , 422 ) self .details = details or [] FastAPI Global Exception Handler from fastapi import FastAPI, Request from fastapi.responses import JSONResponse app = FastAPI() @app.exception_handler( AppError ) async def app_error_handler ( request: Request, exc: AppError ) -> JSONResponse: return JSONResponse( status_code=exc.status_code, content={ "error" : { "code" : exc.code, "message" : str (exc)}}, ) @app.exception_handler( Exception ) async def generic_error_handler ( request: Request, exc: Exception ) -> JSONResponse: # Log full details, return generic message logger.exception( "Unexpected error" , exc_info=exc) return JSONResponse( status_code= 500 , content={ "error" : { "code" : "INTERNAL_ERROR" , "message" : "An unexpected error occurred" }}, ) Go Sentinel Errors and Error Wrapping package domain import "errors" // Sentinel errors for type-checking var ( ErrNotFound = errors.New( "not found" ) ErrUnauthorized = errors.New( "unauthorized" ) ErrConflict = errors.New( "conflict" ) ) // Wrap errors with context — never lose the original func (r *UserRepository) FindByID(ctx context.Context, id string ) (*User, error ) { user, err := r.db.QueryRow(ctx, "SELECT * FROM users WHERE id = $1" , id) if errors.Is(err, sql.ErrNoRows) { return nil , fmt.Errorf( "user %s: %w" , id, ErrNotFound) } if err != nil { return nil , fmt.Errorf( "querying user %s: %w" , id, err) } return user, nil } // At the handler level, unwrap to determine response func (h *Handler) GetUser(w http.ResponseWriter, r *http.Request) { user, err := h.service.GetUser(r.Context(), chi.URLParam(r, "id" )) if err != nil { switch { case errors.Is(err, domain.ErrNotFound): writeError(w, http.StatusNotFound, "not_found" , err.Error()) case errors.Is(err, domain.ErrUnauthorized): writeError(w, http.StatusForbidden, "forbidden" , "Access denied" ) default : slog.Error( "unexpected error" , "err" , err) writeError(w, http.StatusInternalServerError, "internal_error" , "An unexpected error occurred" ) } return } writeJSON(w, http.StatusOK, user) } Retry with Exponential Backoff interface RetryOptions { maxAttempts ?: number baseDelayMs ?: number maxDelayMs ?: number retryIf ?: ( error : unknown ) => boolean } async function withRetry<T>( fn : () => Promise <T>, options : RetryOptions = {}, ): Promise <T> { const { maxAttempts = 3 , baseDelayMs = 500 , maxDelayMs = 10_000 , retryIf = () => true , } = options let lastError : unknown for ( let attempt = 1 ; attempt <= maxAttempts; attempt++) { try { return await fn () } catch (error) { lastError = error if (attempt === maxAttempts || ! retryIf (error)) throw error const jitter = Math . random () * baseDelayMs const delay = Math . min (baseDelayMs * 2 ** (attempt - 1 ) + jitter, maxDelayMs) await new Promise ( resolve => setTimeout (resolve, delay)) } } throw lastError } // Usage: retry transient network errors, not 4xx const data = await withRetry ( () => fetch ( '/api/data' ). then ( r => r. json ()), { maxAttempts : 3 , retryIf : ( error ) => !(error instanceof AppError && error. statusCode < 500 ), }) User-Facing Error Messages Map error codes to human-readable messages. Keep technical details out of user-visible text. const USER_ERROR_MESSAGES : Record < string , string > = { NOT_FOUND : 'The requested item could not be found.' , UNAUTHORIZED : 'Please sign in to continue.' , FORBIDDEN : "You don't have permission to do that." , VALIDATION_ERROR : 'Please check your input and try again.' , RATE_LIMITED : 'Too many requests. Please wait a moment and try again.' , INTERNAL_ERROR : 'Something went wrong on our end. Please try again later.' , } export function getUserMessage ( code : string ): string { return USER_ERROR_MESSAGES [code] ?? USER_ERROR_MESSAGES . INTERNAL_ERROR } Error Handling Checklist Before merging any code that touches error handling: Every catch block handles, re-throws, or logs — no silent swallowing API errors follow the standard envelope { error: { code, message } } User-facing messages contain no stack traces or internal details Full error context is logged server-side Custom error classes extend a base AppError with a code field Async functions surface errors to callers — no fire-and-forget without fallback Retry logic only retries retriable errors (not 4xx client errors) React components are wrapped in ErrorBoundary for rendering errors
Agent 识别该技能的关键词,点击任意一个即可复制。

该技能未提供触发词。

下载的 .skill 包内含以下字段。
字段 说明
format格式标识(skill/v1)
skill_id技能唯一 ID
name技能名称
version版本号
description技能描述
category所属分类(数组)
trigger_words触发词列表
tags标签列表
source来源标识
source_url来源链接(本页地址)
exported_at导出时间(每次下载生成)
system_prompt系统提示词正文
model_config模型参数:provider / model / temperature / max_tokens / top_p
examples示例
install_guide各平台导入说明(Coze / Dify / Claude / 自定义框架)
同一份技能可按不同平台格式导出。
.skill 标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用 下载
.skillpro 增强格式,额外含脚本 / 工具 / 依赖 / 钩子占位 下载
.json 纯 JSON 导出,只含 system_prompt 与模型参数 下载
Coze 带 frontmatter 的 Markdown,Coze 平台导入用 下载
Dify Dify DSL,创建应用后直接导入 下载

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。