skills/error-handling/SKILL.md
에러 핸들링 패턴 및 전략을 위한 가이드를 실행합니다.
npx skillsauth add excatt/superclaude-plusplus error-handlingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
에러 핸들링 패턴 및 전략을 위한 가이드를 실행합니다.
- 예상 가능, 복구 가능
- 네트워크 타임아웃
- 잘못된 사용자 입력
- 외부 서비스 장애
→ 처리: 적절한 응답, 재시도, 폴백
- 버그, 복구 불가
- null 참조
- 잘못된 타입
- 로직 오류
→ 처리: 수정 필요, 프로세스 재시작
class AppError extends Error {
constructor(
message: string,
public code: string,
public statusCode: number = 500,
public isOperational: boolean = true
) {
super(message);
this.name = this.constructor.name;
Error.captureStackTrace(this, this.constructor);
}
}
class ValidationError extends AppError {
constructor(message: string, public fields: Record<string, string>) {
super(message, 'VALIDATION_ERROR', 400);
}
}
class NotFoundError extends AppError {
constructor(resource: string) {
super(`${resource} not found`, 'NOT_FOUND', 404);
}
}
class UnauthorizedError extends AppError {
constructor(message = 'Unauthorized') {
super(message, 'UNAUTHORIZED', 401);
}
}
class AppError(Exception):
def __init__(self, message, code, status_code=500, is_operational=True):
super().__init__(message)
self.code = code
self.status_code = status_code
self.is_operational = is_operational
class ValidationError(AppError):
def __init__(self, message, fields):
super().__init__(message, 'VALIDATION_ERROR', 400)
self.fields = fields
class NotFoundError(AppError):
def __init__(self, resource):
super().__init__(f'{resource} not found', 'NOT_FOUND', 404)
// 에러 핸들링 미들웨어
const errorHandler = (
err: Error,
req: Request,
res: Response,
next: NextFunction
) => {
// 로깅
logger.error({
err,
path: req.path,
method: req.method,
traceId: req.traceId,
});
// 응답
if (err instanceof AppError) {
return res.status(err.statusCode).json({
error: {
code: err.code,
message: err.message,
...(err instanceof ValidationError && { fields: err.fields }),
},
});
}
// 알 수 없는 에러
res.status(500).json({
error: {
code: 'INTERNAL_ERROR',
message: 'Something went wrong',
},
});
};
type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
function parseJSON<T>(json: string): Result<T> {
try {
return { success: true, data: JSON.parse(json) };
} catch (e) {
return { success: false, error: e as Error };
}
}
// 사용
const result = parseJSON<User>(data);
if (result.success) {
console.log(result.data);
} else {
console.error(result.error);
}
class Either<L, R> {
private constructor(
private left: L | null,
private right: R | null
) {}
static left<L, R>(value: L): Either<L, R> {
return new Either(value, null);
}
static right<L, R>(value: R): Either<L, R> {
return new Either(null, value);
}
map<T>(fn: (r: R) => T): Either<L, T> {
return this.right !== null
? Either.right(fn(this.right))
: Either.left(this.left!);
}
}
async function withRetry<T>(
fn: () => Promise<T>,
options: {
maxRetries: number;
baseDelay: number;
maxDelay: number;
}
): Promise<T> {
let lastError: Error;
for (let i = 0; i <= options.maxRetries; i++) {
try {
return await fn();
} catch (error) {
lastError = error as Error;
if (i === options.maxRetries) break;
const delay = Math.min(
options.baseDelay * Math.pow(2, i),
options.maxDelay
);
await sleep(delay + Math.random() * 1000); // jitter
}
}
throw lastError!;
}
class CircuitBreaker {
private failures = 0;
private lastFailure: Date | null = null;
private state: 'CLOSED' | 'OPEN' | 'HALF_OPEN' = 'CLOSED';
constructor(
private threshold: number = 5,
private timeout: number = 30000
) {}
async execute<T>(fn: () => Promise<T>): Promise<T> {
if (this.state === 'OPEN') {
if (Date.now() - this.lastFailure!.getTime() > this.timeout) {
this.state = 'HALF_OPEN';
} else {
throw new Error('Circuit is OPEN');
}
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
private onSuccess() {
this.failures = 0;
this.state = 'CLOSED';
}
private onFailure() {
this.failures++;
this.lastFailure = new Date();
if (this.failures >= this.threshold) {
this.state = 'OPEN';
}
}
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input data",
"details": [
{ "field": "email", "message": "Invalid email format" },
{ "field": "age", "message": "Must be positive number" }
],
"traceId": "abc-123"
}
}
## Error Handling Strategy
### Error Classes
```typescript
// 커스텀 에러 클래스
// 전역 에러 핸들러
| 상황 | 코드 | HTTP | 메시지 | |------|------|------|--------| | 유효성 검증 실패 | VALIDATION_ERROR | 400 | Invalid input |
---
요청에 맞는 에러 핸들링 전략을 설계하세요.
testing
사용자 계획을 기존 도메인 모델에 대해 stress-test하는 인터뷰 세션. 용어를 날카롭게 다듬고, 결정이 굳어질 때마다 CONTEXT.md(도메인 어휘 사전)와 ADR을 인라인으로 갱신한다. 새 기능 요구사항 탐색은 `/brainstorm`을, 기존 도메인 모델·용어와의 정합성 점검은 이 스킬을 사용한다.
development
# Excel (XLSX) Spreadsheet Skill Claude Code supports comprehensive spreadsheet operations through the **xlsx** skill, enabling creation, editing, and analysis of Excel files (.xlsx, .xlsm, .csv, .tsv). ## Trigger - When user needs Excel spreadsheet creation or editing - Financial modeling or data analysis required - Spreadsheet formulas and calculations needed - Data import from CSV/TSV files ## Core Capabilities **Primary functions include:** - Creating new spreadsheets with formulas and f
tools
Generate structured implementation workflows from PRDs and feature requirements
development
실시간 통신 설계 가이드를 실행합니다.