allra-error-handling
Allra 백엔드 에러 핸들링 및 예외 처리 표준. Use when handling errors, creating custom exceptions, or implementing error responses.
Best use case
allra-error-handling is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Allra 백엔드 에러 핸들링 및 예외 처리 표준. Use when handling errors, creating custom exceptions, or implementing error responses.
Teams using allra-error-handling should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/allra-error-handling/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How allra-error-handling Compares
| Feature / Agent | allra-error-handling | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Allra 백엔드 에러 핸들링 및 예외 처리 표준. Use when handling errors, creating custom exceptions, or implementing error responses.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Allra Backend 에러 핸들링 표준
Allra 백엔드 팀의 에러 핸들링, 예외 처리, 로깅 표준을 정의합니다.
## 예외 클래스 설계
### 1. 비즈니스 예외 계층 구조
```java
// 최상위 비즈니스 예외
public abstract class BusinessException extends RuntimeException {
private final ErrorCode errorCode;
protected BusinessException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
}
protected BusinessException(ErrorCode errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
public ErrorCode getErrorCode() {
return errorCode;
}
public int getStatus() {
return errorCode.getStatus();
}
}
// ErrorCode Enum (예시)
public enum ErrorCode {
// 400 Bad Request
INVALID_INPUT_VALUE(400, "E001", "잘못된 입력값입니다"),
// 401 Unauthorized
UNAUTHORIZED(401, "E101", "인증이 필요합니다"),
INVALID_TOKEN(401, "E102", "유효하지 않은 토큰입니다"),
// 403 Forbidden
FORBIDDEN(403, "E201", "권한이 없습니다"),
// 404 Not Found
ENTITY_NOT_FOUND(404, "E301", "요청한 리소스를 찾을 수 없습니다"),
USER_NOT_FOUND(404, "E302", "사용자를 찾을 수 없습니다"),
// 409 Conflict
DUPLICATE_RESOURCE(409, "E401", "이미 존재하는 리소스입니다"),
// 500 Internal Server Error
INTERNAL_SERVER_ERROR(500, "E999", "서버 내부 오류가 발생했습니다");
private final int status;
private final String code;
private final String message;
ErrorCode(int status, String code, String message) {
this.status = status;
this.code = code;
this.message = message;
}
// getters...
}
```
**참고**: ErrorCode 체계(E001, E101 등)와 메시지 언어(한국어/영어)는 프로젝트별로 다를 수 있습니다.
### 2. 도메인별 예외 클래스
```java
// 엔티티를 찾을 수 없을 때
public class EntityNotFoundException extends BusinessException {
public EntityNotFoundException(String entityName, Long id) {
super(ErrorCode.ENTITY_NOT_FOUND,
String.format("%s(id=%d)을 찾을 수 없습니다", entityName, id));
}
}
// 사용자 관련 예외
public class UserNotFoundException extends BusinessException {
public UserNotFoundException(Long userId) {
super(ErrorCode.USER_NOT_FOUND,
String.format("사용자(id=%d)를 찾을 수 없습니다", userId));
}
}
// 중복 리소스 예외
public class DuplicateResourceException extends BusinessException {
public DuplicateResourceException(String resourceName, String field, String value) {
super(ErrorCode.DUPLICATE_RESOURCE,
String.format("%s의 %s=%s가 이미 존재합니다", resourceName, field, value));
}
}
// 인증/인가 예외
public class UnauthorizedException extends BusinessException {
public UnauthorizedException() {
super(ErrorCode.UNAUTHORIZED);
}
}
public class ForbiddenException extends BusinessException {
public ForbiddenException(String message) {
super(ErrorCode.FORBIDDEN, message);
}
}
```
## Global Exception Handler
### @RestControllerAdvice 구현
```java
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
// 비즈니스 예외 처리
@ExceptionHandler(BusinessException.class)
protected ResponseEntity<ErrorResponse> handleBusinessException(BusinessException e) {
log.warn("BusinessException: code={}, message={}",
e.getErrorCode().getCode(), e.getMessage());
ErrorResponse response = ErrorResponse.of(e.getErrorCode(), e.getMessage());
return ResponseEntity
.status(e.getStatus())
.body(response);
}
// Bean Validation 예외 처리
@ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(
MethodArgumentNotValidException e) {
log.warn("MethodArgumentNotValidException: {}", e.getMessage());
List<ErrorResponse.FieldError> fieldErrors = e.getBindingResult()
.getFieldErrors()
.stream()
.map(error -> new ErrorResponse.FieldError(
error.getField(),
error.getRejectedValue() != null ? error.getRejectedValue().toString() : null,
error.getDefaultMessage()
))
.toList();
ErrorResponse response = ErrorResponse.of(ErrorCode.INVALID_INPUT_VALUE, fieldErrors);
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(response);
}
// 예상하지 못한 예외 처리
@ExceptionHandler(Exception.class)
protected ResponseEntity<ErrorResponse> handleException(Exception e) {
log.error("Unexpected exception occurred", e);
ErrorResponse response = ErrorResponse.of(
ErrorCode.INTERNAL_SERVER_ERROR,
"서버 오류가 발생했습니다"
);
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(response);
}
}
```
## 에러 응답 형식 (Allra 표준)
### ErrorResponse DTO
```java
public record ErrorResponse(
String code,
String message,
List<FieldError> errors,
LocalDateTime timestamp
) {
public static ErrorResponse of(ErrorCode errorCode) {
return new ErrorResponse(
errorCode.getCode(),
errorCode.getMessage(),
Collections.emptyList(),
LocalDateTime.now()
);
}
public static ErrorResponse of(ErrorCode errorCode, String message) {
return new ErrorResponse(
errorCode.getCode(),
message,
Collections.emptyList(),
LocalDateTime.now()
);
}
public static ErrorResponse of(ErrorCode errorCode, List<FieldError> errors) {
return new ErrorResponse(
errorCode.getCode(),
errorCode.getMessage(),
errors,
LocalDateTime.now()
);
}
public record FieldError(
String field,
String rejectedValue,
String message
) {}
}
```
**참고**: 에러 응답 구조는 프로젝트별로 커스터마이징할 수 있습니다. 중요한 것은 일관성 있는 형식을 유지하는 것입니다.
### 에러 응답 예시
**단일 에러:**
```json
{
"code": "E302",
"message": "사용자(id=123)를 찾을 수 없습니다",
"errors": [],
"timestamp": "2024-12-17T10:30:00"
}
```
**Validation 에러:**
```json
{
"code": "E001",
"message": "잘못된 입력값입니다",
"errors": [
{
"field": "email",
"rejectedValue": "invalid-email",
"message": "올바른 이메일 형식이 아닙니다"
}
],
"timestamp": "2024-12-17T10:30:00"
}
```
## 서비스 레이어에서 예외 사용
### 1. 엔티티 조회 시 예외 처리
```java
@Service
public class UserService {
private final UserRepository userRepository;
@Transactional(readOnly = true)
public User findUserById(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
}
}
```
### 2. 비즈니스 로직 검증
```java
@Service
public class UserService {
@Transactional
public User createUser(SignUpRequest request) {
// 중복 체크
if (userRepository.existsByEmail(request.email())) {
throw new DuplicateResourceException("User", "email", request.email());
}
User user = User.create(request.email(), request.password());
return userRepository.save(user);
}
@Transactional
public void deleteUser(Long id, Long currentUserId) {
User user = userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
// 권한 체크
if (!user.getId().equals(currentUserId)) {
throw new ForbiddenException("본인의 계정만 삭제할 수 있습니다");
}
userRepository.delete(user);
}
}
```
## 로깅 전략
### 1. 로깅 레벨
```java
@Service
@Slf4j
public class UserService {
// DEBUG: 개발 시 디버깅 정보
log.debug("Finding user by id: {}", id);
// INFO: 정상적인 비즈니스 플로우
log.info("User created successfully: userId={}", user.getId());
// WARN: 비즈니스 예외 (예상된 에러)
log.warn("User not found: userId={}", id);
// ERROR: 시스템 예외 (예상하지 못한 에러)
log.error("Unexpected error occurred while creating user", e);
}
```
**참고**: 로깅 레벨과 형식은 프로젝트의 로깅 정책에 따라 다를 수 있습니다.
### 2. 로깅 포맷
```java
// ✅ 권장: 구조화된 정보
log.info("User signup completed: userId={}, email={}, signupAt={}",
user.getId(), user.getEmail(), LocalDateTime.now());
log.warn("Failed login attempt: email={}, reason={}",
email, "Invalid password");
// ❌ 피하기: 단순 문자열 연결
log.info("User " + user.getId() + " signed up");
```
## When to Use This Skill
이 skill은 다음 상황에서 자동으로 적용됩니다:
- 커스텀 예외 클래스 생성
- Service 레이어에서 예외 throw
- Global Exception Handler 구현
- 에러 응답 DTO 작성
- 로깅 코드 작성
## Checklist
에러 핸들링 코드 작성 시 확인사항:
- [ ] 비즈니스 예외는 BusinessException을 상속하는가?
- [ ] ErrorCode enum에 적절한 HTTP 상태 코드가 정의되었는가?
- [ ] Global Exception Handler에 예외 처리가 추가되었는가?
- [ ] 에러 응답이 표준 형식을 따르는가?
- [ ] 비즈니스 예외는 WARN 레벨로 로깅하는가?
- [ ] 시스템 예외는 ERROR 레벨로 로깅하는가?
- [ ] 민감한 정보(비밀번호 등)가 로그에 포함되지 않는가?
- [ ] orElseThrow를 사용해 Optional을 처리하는가?Related Skills
anth-data-handling
Implement data privacy, PII handling, and compliance patterns for Claude API. Use when handling sensitive data, implementing PII redaction, or configuring data retention for GDPR/CCPA compliance with Claude. Trigger with phrases like "anthropic data privacy", "claude PII", "anthropic gdpr", "claude data handling", "redact data claude".
anth-common-errors
Diagnose and fix Anthropic Claude API errors by HTTP status code. Use when encountering API errors, debugging failed requests, or troubleshooting authentication, rate limiting, or input validation issues. Trigger with phrases like "anthropic error", "claude api error", "fix anthropic 429", "claude not working", "debug claude api".
anima-common-errors
Diagnose and fix common Anima SDK design-to-code errors. Use when encountering Figma token errors, code generation failures, node not found issues, or output quality problems. Trigger: "anima error", "anima not working", "anima debug", "figma to code error".
algolia-data-handling
Implement Algolia data handling: record transforms, PII filtering before indexing, data retention, GDPR/CCPA compliance with Algolia's deleteByQuery and Insights deletion. Trigger: "algolia data", "algolia PII", "algolia GDPR", "algolia data retention", "algolia privacy", "algolia CCPA", "algolia data sync".
algolia-common-errors
Diagnose and fix the top Algolia API errors: 400, 403, 404, 429, ApiError, RetryError, and indexing failures. Trigger: "algolia error", "fix algolia", "algolia not working", "debug algolia", "algolia 429", "algolia 403".
alchemy-common-errors
Diagnose and fix common Alchemy SDK and Web3 API errors. Use when encountering rate limits, RPC failures, invalid parameters, or blockchain query errors with the Alchemy SDK. Trigger: "alchemy error", "alchemy not working", "alchemy 429", "alchemy debug", "fix alchemy issue".
adobe-data-handling
Implement data handling for Adobe APIs including PII redaction in logs, Firefly content policy compliance, PDF document data classification, and GDPR/CCPA data subject access requests via Adobe Privacy Service. Trigger with phrases like "adobe data", "adobe PII", "adobe GDPR", "adobe data retention", "adobe privacy", "adobe content policy".
adobe-common-errors
Diagnose and fix common Adobe API errors across Firefly Services, PDF Services, Photoshop API, and Adobe I/O Events. Use when encountering Adobe errors, debugging failed requests, or troubleshooting integration issues. Trigger with phrases like "adobe error", "fix adobe", "adobe not working", "debug adobe", "adobe 403", "adobe 429".
abridge-common-errors
Diagnose and fix common Abridge clinical AI integration errors. Use when encountering EHR connectivity failures, note generation errors, audio streaming issues, or FHIR validation problems with Abridge. Trigger: "abridge error", "abridge not working", "abridge debug", "fix abridge issue", "abridge troubleshoot".
troubleshooting-dbt-job-errors
Diagnoses dbt Cloud/platform job failures by analyzing run logs, querying the Admin API, reviewing git history, and investigating data issues. Use when a dbt Cloud/platform job fails and you need to diagnose the root cause, especially when error messages are unclear or when intermittent failures occur. Do not use for local dbt development errors.
go-error-handling
Use when writing Go code that returns, wraps, or handles errors — choosing between sentinel errors, custom types, and fmt.Errorf (%w vs %v), structuring error flow, or deciding whether to log or return. Also use when propagating errors across package boundaries or using errors.Is/As, even if the user doesn't ask about error strategy. Does not cover panic/recover patterns (see go-defensive).
fp-ts-errors
Handle errors as values using fp-ts Either and TaskEither for cleaner, more predictable TypeScript code. Use when implementing error handling patterns with fp-ts.