Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:52:14 +08:00
commit 5aa901f301
16 changed files with 1105 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
{
"name": "api-error-handler",
"description": "Implement standardized error handling with proper HTTP status codes",
"version": "1.0.0",
"author": {
"name": "Jeremy Longshore",
"email": "[email protected]"
},
"skills": [
"./skills"
],
"commands": [
"./commands"
]
}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# api-error-handler
Implement standardized error handling with proper HTTP status codes

View File

@@ -0,0 +1,550 @@
---
description: Implement standardized API error handling
shortcut: errors
---
# Implement Error Handling
Create standardized, production-ready error handling middleware with proper HTTP status codes, consistent error formats, and comprehensive logging. This command generates custom error classes, middleware, and error recovery strategies for Node.js, Python, and other backend frameworks.
## Design Decisions
**Why standardized error handling matters:**
- **Client experience**: Consistent error formats make client integration predictable
- **Debugging**: Structured errors with context accelerate troubleshooting
- **Security**: Proper error handling prevents information leakage in production
- **Monitoring**: Standardized errors integrate cleanly with observability tools
**Alternatives considered:**
- **HTTP-only errors**: Simpler but lacks context for debugging
- **Framework defaults**: Inconsistent across endpoints, lacks business context
- **Exception-based only**: Can leak sensitive information, harder to test
**This approach balances**: Developer experience, security, debugging, and API consistency.
## When to Use
Use this command when:
- Starting a new API project that needs error handling
- Refactoring inconsistent error responses across endpoints
- Adding error monitoring and alerting to an existing API
- Migrating from generic framework errors to business-specific errors
- Implementing error handling for microservices that need consistency
Don't use when:
- Your framework's default error handling already meets your needs
- Building proof-of-concept code without production requirements
- Working with legacy systems that can't adopt new error formats
## Prerequisites
- Node.js 16+ (for Express/Fastify examples) or Python 3.8+ (for Flask/FastAPI)
- Existing API project structure
- Basic understanding of HTTP status codes (4xx client errors, 5xx server errors)
- (Optional) Logging framework installed (Winston, Pino, Structlog)
- (Optional) Monitoring service (Sentry, DataDog, New Relic)
## Process
1. **Generate Custom Error Classes**
- Create base error class with HTTP status codes
- Define specific error types (ValidationError, NotFoundError, AuthError)
- Add error codes for programmatic handling
2. **Build Error Middleware**
- Catch all errors in centralized handler
- Format errors consistently (RFC 7807 Problem Details or custom)
- Handle both operational and programmer errors
3. **Configure Environment-Specific Behavior**
- Development: Include stack traces, detailed messages
- Production: Sanitize errors, log internally, return safe messages
4. **Integrate Logging**
- Log all errors with context (request ID, user, endpoint)
- Add severity levels (error, warning, critical)
- Include metadata for troubleshooting
5. **Add Error Recovery**
- Graceful degradation strategies
- Retry logic for transient failures
- Circuit breaker integration
## Output Format
### Express.js Error Handler
```javascript
// errors/AppError.js
class AppError extends Error {
constructor(message, statusCode, errorCode = null) {
super(message);
this.statusCode = statusCode;
this.errorCode = errorCode;
this.isOperational = true;
this.timestamp = new Date().toISOString();
Error.captureStackTrace(this, this.constructor);
}
}
class ValidationError extends AppError {
constructor(message, errors = []) {
super(message, 400, 'VALIDATION_ERROR');
this.errors = errors;
}
}
class NotFoundError extends AppError {
constructor(resource) {
super(`${resource} not found`, 404, 'NOT_FOUND');
this.resource = resource;
}
}
class UnauthorizedError extends AppError {
constructor(message = 'Unauthorized') {
super(message, 401, 'UNAUTHORIZED');
}
}
class ForbiddenError extends AppError {
constructor(message = 'Forbidden') {
super(message, 403, 'FORBIDDEN');
}
}
module.exports = { AppError, ValidationError, NotFoundError, UnauthorizedError, ForbiddenError };
// middleware/errorHandler.js
const logger = require('../utils/logger');
const errorHandler = (err, req, res, next) => {
// Default to 500 server error
let statusCode = err.statusCode || 500;
let message = err.message || 'Internal Server Error';
// Log error with context
logger.error({
message: err.message,
statusCode,
errorCode: err.errorCode,
stack: err.stack,
path: req.path,
method: req.method,
requestId: req.id,
userId: req.user?.id,
ip: req.ip
});
// Production: Don't leak error details
if (process.env.NODE_ENV === 'production' && !err.isOperational) {
message = 'An unexpected error occurred';
statusCode = 500;
}
// Send error response
res.status(statusCode).json({
error: {
message,
code: err.errorCode,
statusCode,
timestamp: err.timestamp || new Date().toISOString(),
path: req.path,
...(process.env.NODE_ENV === 'development' && { stack: err.stack }),
...(err.errors && { details: err.errors })
}
});
};
module.exports = errorHandler;
```
### FastAPI (Python) Error Handler
```python
# errors/exceptions.py
from typing import Optional, Any, Dict
from fastapi import HTTPException
from datetime import datetime
class AppError(HTTPException):
def __init__(
self,
status_code: int,
message: str,
error_code: Optional[str] = None,
details: Optional[Dict[str, Any]] = None
):
self.status_code = status_code
self.message = message
self.error_code = error_code
self.details = details or {}
self.timestamp = datetime.utcnow().isoformat()
super().__init__(status_code=status_code, detail=message)
class ValidationError(AppError):
def __init__(self, message: str, errors: list = None):
super().__init__(
status_code=400,
message=message,
error_code="VALIDATION_ERROR",
details={"errors": errors or []}
)
class NotFoundError(AppError):
def __init__(self, resource: str):
super().__init__(
status_code=404,
message=f"{resource} not found",
error_code="NOT_FOUND",
details={"resource": resource}
)
class UnauthorizedError(AppError):
def __init__(self, message: str = "Unauthorized"):
super().__init__(
status_code=401,
message=message,
error_code="UNAUTHORIZED"
)
# main.py
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import logging
app = FastAPI()
logger = logging.getLogger(__name__)
@app.exception_handler(AppError)
async def app_error_handler(request: Request, exc: AppError):
logger.error(
f"AppError: {exc.message}",
extra={
"status_code": exc.status_code,
"error_code": exc.error_code,
"path": request.url.path,
"method": request.method
}
)
return JSONResponse(
status_code=exc.status_code,
content={
"error": {
"message": exc.message,
"code": exc.error_code,
"statusCode": exc.status_code,
"timestamp": exc.timestamp,
"path": str(request.url.path),
**exc.details
}
}
)
@app.exception_handler(Exception)
async def generic_error_handler(request: Request, exc: Exception):
logger.exception("Unhandled exception", exc_info=exc)
return JSONResponse(
status_code=500,
content={
"error": {
"message": "Internal server error",
"code": "INTERNAL_ERROR",
"statusCode": 500,
"timestamp": datetime.utcnow().isoformat()
}
}
)
```
## Example Usage
### Example 1: Handling Validation Errors
```javascript
const { ValidationError } = require('./errors/AppError');
const { body, validationResult } = require('express-validator');
router.post('/users',
[
body('email').isEmail().normalizeEmail(),
body('password').isLength({ min: 8 }),
body('name').trim().notEmpty()
],
async (req, res, next) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
throw new ValidationError('Validation failed', errors.array());
}
const user = await createUser(req.body);
res.status(201).json(user);
} catch (error) {
next(error);
}
}
);
// Response for invalid input:
// {
// "error": {
// "message": "Validation failed",
// "code": "VALIDATION_ERROR",
// "statusCode": 400,
// "timestamp": "2025-10-11T12:00:00.000Z",
// "path": "/users",
// "details": [
// { "field": "email", "message": "Invalid email format" },
// { "field": "password", "message": "Password must be at least 8 characters" }
// ]
// }
// }
```
### Example 2: Resource Not Found
```python
from fastapi import APIRouter
from errors.exceptions import NotFoundError
router = APIRouter()
@router.get("/users/{user_id}")
async def get_user(user_id: int):
user = await db.get_user(user_id)
if not user:
raise NotFoundError("User")
return user
# Response:
# {
# "error": {
# "message": "User not found",
# "code": "NOT_FOUND",
# "statusCode": 404,
# "timestamp": "2025-10-11T12:00:00.000Z",
# "path": "/users/123",
# "details": {
# "resource": "User"
# }
# }
# }
```
### Example 3: Error with Retry Strategy
```javascript
const { AppError } = require('./errors/AppError');
const retry = require('async-retry');
async function callExternalAPI(endpoint) {
return retry(async (bail, attempt) => {
try {
const response = await fetch(endpoint);
if (!response.ok) {
// Don't retry client errors
if (response.status >= 400 && response.status < 500) {
bail(new AppError('External API error', response.status));
return;
}
// Retry server errors
throw new Error(`API returned ${response.status}`);
}
return response.json();
} catch (error) {
console.log(`Attempt ${attempt} failed: ${error.message}`);
throw error;
}
}, {
retries: 3,
minTimeout: 1000,
maxTimeout: 5000
});
}
```
## Error Handling
**Common issues and solutions:**
**Problem**: Errors logged multiple times
- **Cause**: Error handlers at multiple middleware layers
- **Solution**: Log only in the central error handler, not in route handlers
**Problem**: Stack traces visible in production
- **Cause**: Environment check not working correctly
- **Solution**: Verify `NODE_ENV=production` is set, check conditional logic
**Problem**: Lost error context (request ID, user info)
- **Cause**: Context not attached to request object
- **Solution**: Use middleware to attach request ID, user before error handler
**Problem**: Async errors not caught
- **Cause**: Missing try-catch or next() in async routes
- **Solution**: Use express-async-errors or wrap all async routes
**Problem**: Database connection errors crashing app
- **Cause**: Uncaught promise rejections
- **Solution**: Add process-level error handlers:
```javascript
process.on('unhandledRejection', (reason, promise) => {
logger.error('Unhandled Rejection', { reason, promise });
// Optionally exit: process.exit(1);
});
process.on('uncaughtException', (error) => {
logger.error('Uncaught Exception', { error });
process.exit(1); // Must exit, app is in undefined state
});
```
## Configuration
### Error Handler Options
```javascript
const errorHandlerOptions = {
// Include stack traces
showStack: process.env.NODE_ENV === 'development',
// Log level for different error types
logLevel: {
operational: 'error',
programmer: 'critical'
},
// Send errors to monitoring service
reportToMonitoring: process.env.NODE_ENV === 'production',
// Sanitize sensitive fields
sanitizeFields: ['password', 'ssn', 'creditCard'],
// Custom error formatters
formatters: {
json: (err) => ({ error: err.toJSON() }),
xml: (err) => convertToXML(err)
}
};
```
## Best Practices
DO:
- Log all errors with sufficient context for debugging
- Use specific error classes for different failure scenarios
- Return consistent error format across all endpoints
- Sanitize errors in production (no stack traces, no sensitive data)
- Include correlation IDs for tracing errors across services
- Test error handling as thoroughly as success cases
- Document error codes and responses in API documentation
DON'T:
- Expose internal implementation details in error messages
- Log sensitive data (passwords, tokens, PII)
- Ignore errors or swallow exceptions silently
- Use generic "Error occurred" messages without context
- Return different error formats from different endpoints
- Forget to handle async errors (use try-catch or error middleware)
- Let programmer errors (bugs) be handled the same as operational errors
TIPS:
- Use error codes clients can handle programmatically (`INSUFFICIENT_FUNDS`, `RATE_LIMIT_EXCEEDED`)
- Provide actionable error messages ("Email already registered, try logging in" not "Duplicate entry")
- Group related errors with similar status codes (all validation = 400, all auth = 401/403)
- Consider RFC 7807 Problem Details format for standardization
- Add request IDs to errors for log correlation
- Monitor error rates and alert on anomalies
## Related Commands
- `/validate-api-responses` - Validate API responses match schemas
- `/setup-logging` - Configure structured logging for errors
- `/scan-api-security` - Scan for security vulnerabilities in error handling
- `/create-monitoring` - Set up error monitoring dashboards
- `/generate-rest-api` - Generate REST API with built-in error handling
## Performance Considerations
- **Error creation overhead**: Custom error classes add minimal overhead (~1-2ms)
- **Stack trace capture**: Can be expensive in hot paths, consider disabling in production
- **Logging**: Use async logging to avoid blocking request threads
- **Monitoring**: Batch error reports to external services (Sentry, DataDog)
- **Memory leaks**: Ensure errors don't hold references to large objects
**Optimization strategies:**
```javascript
// Disable stack traces in production for performance
if (process.env.NODE_ENV === 'production') {
Error.stackTraceLimit = 0;
}
// Use structured logging with async writes
const logger = winston.createLogger({
transports: [
new winston.transports.File({
filename: 'error.log',
level: 'error'
})
]
});
```
## Security Considerations
- **Information disclosure**: Never expose database errors, file paths, or internal IDs
- **Error-based enumeration**: Avoid revealing if resources exist ("Invalid credentials" not "User not found")
- **DoS via errors**: Rate limit error-triggering requests
- **Log injection**: Sanitize user input before logging
- **Sensitive data in logs**: Redact passwords, tokens, SSNs before logging
**Security checklist:**
```javascript
// BAD: Exposes internal structure
throw new Error(`User ${userId} not found in users table`);
// GOOD: Generic message
throw new NotFoundError('User');
// BAD: Reveals existence
if (!user) throw new Error('User not found');
if (password !== user.password) throw new Error('Wrong password');
// GOOD: Generic auth failure
if (!user || password !== user.password) {
throw new UnauthorizedError('Invalid credentials');
}
```
## Troubleshooting
**Error handler not catching errors:**
1. Ensure error handler is registered AFTER all routes
2. Check async routes call `next(error)` or use express-async-errors
3. Verify middleware order: routes → 404 handler → error handler
**Errors not logged:**
1. Check logger configuration and file permissions
2. Verify log level settings (error should be logged at all levels)
3. Test logger independently before integration
**Production errors too verbose:**
1. Verify NODE_ENV=production environment variable
2. Check conditional stack trace logic
3. Test with actual production config locally
**Error monitoring not working:**
1. Verify API keys for Sentry/DataDog/New Relic
2. Check network connectivity to monitoring service
3. Test error reporting independently
## Version History
- **1.0.0** (2025-10-11): Initial release with Express and FastAPI examples
- Custom error classes (ValidationError, NotFoundError, AuthError)
- Environment-specific error formatting
- Structured logging integration
- Error recovery patterns

93
plugin.lock.json Normal file
View File

@@ -0,0 +1,93 @@
{
"$schema": "internal://schemas/plugin.lock.v1.json",
"pluginId": "gh:jeremylongshore/claude-code-plugins-plus:plugins/api-development/api-error-handler",
"normalized": {
"repo": null,
"ref": "refs/tags/v20251128.0",
"commit": "049c0462691b54459056b3b96342bb183be55818",
"treeHash": "2ce1da5b86546879cbdd232f16338e0311ec8b9fb15b37c31d89a8be696daee2",
"generatedAt": "2025-11-28T10:18:06.016976Z",
"toolVersion": "publish_plugins.py@0.2.0"
},
"origin": {
"remote": "git@github.com:zhongweili/42plugin-data.git",
"branch": "master",
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
},
"manifest": {
"name": "api-error-handler",
"description": "Implement standardized error handling with proper HTTP status codes",
"version": "1.0.0"
},
"content": {
"files": [
{
"path": "README.md",
"sha256": "175e0b7b984822779cacb43294a19114800d5218a77751ecfb0a6d8861310837"
},
{
"path": ".claude-plugin/plugin.json",
"sha256": "38304e3313bd5450d8cd9c3e9dd1b2d708d5522e88e2f69b7de3dcdc8bd71175"
},
{
"path": "commands/implement-error-handling.md",
"sha256": "0cd7ce652ff8f4c0da73a9990e731712d9633c108307e6af5d9d8ed877854f09"
},
{
"path": "skills/skill-adapter/references/examples.md",
"sha256": "922bbc3c4ebf38b76f515b5c1998ebde6bf902233e00e2c5a0e9176f975a7572"
},
{
"path": "skills/skill-adapter/references/best-practices.md",
"sha256": "c8f32b3566252f50daacd346d7045a1060c718ef5cfb07c55a0f2dec5f1fb39e"
},
{
"path": "skills/skill-adapter/references/README.md",
"sha256": "cc46b97f6435d5e3f0b9f6dd4dd83d687af4af7ffc5e247fcb3616e9816be5c1"
},
{
"path": "skills/skill-adapter/scripts/helper-template.sh",
"sha256": "0881d5660a8a7045550d09ae0acc15642c24b70de6f08808120f47f86ccdf077"
},
{
"path": "skills/skill-adapter/scripts/validation.sh",
"sha256": "92551a29a7f512d2036e4f1fb46c2a3dc6bff0f7dde4a9f699533e446db48502"
},
{
"path": "skills/skill-adapter/scripts/README.md",
"sha256": "1b82d8761fbd8f2fd92b3d00a35f64543a245d8f30ba200f36ff8f2f2de5d629"
},
{
"path": "skills/skill-adapter/assets/test-data.json",
"sha256": "ac17dca3d6e253a5f39f2a2f1b388e5146043756b05d9ce7ac53a0042eee139d"
},
{
"path": "skills/skill-adapter/assets/README.md",
"sha256": "6f9615ffa1ebf4e6950135055bb60b6dd8ddd6412312f84a19c25ec33f0a8f80"
},
{
"path": "skills/skill-adapter/assets/error_response_template.json",
"sha256": "2f563aeece90c9a65d0fc4fbab364bcdc1ab56ee479da914a14e32839e275c48"
},
{
"path": "skills/skill-adapter/assets/skill-schema.json",
"sha256": "f5639ba823a24c9ac4fb21444c0717b7aefde1a4993682897f5bf544f863c2cd"
},
{
"path": "skills/skill-adapter/assets/error_code_prefix_mapping.json",
"sha256": "c047172ca542b73118334dbbea54a679f655791bceb7752ab33085627d807b94"
},
{
"path": "skills/skill-adapter/assets/config-template.json",
"sha256": "0c2ba33d2d3c5ccb266c0848fc43caa68a2aa6a80ff315d4b378352711f83e1c"
}
],
"dirSha256": "2ce1da5b86546879cbdd232f16338e0311ec8b9fb15b37c31d89a8be696daee2"
},
"security": {
"scannedAt": null,
"scannerVersion": null,
"flags": []
}
}

View File

@@ -0,0 +1,6 @@
# Assets
Bundled resources for api-error-handler skill
- [ ] error_response_template.json: A JSON template for consistent error responses.
- [ ] error_code_prefix_mapping.json: A mapping of error code prefixes to specific API modules or services.

View File

@@ -0,0 +1,32 @@
{
"skill": {
"name": "skill-name",
"version": "1.0.0",
"enabled": true,
"settings": {
"verbose": false,
"autoActivate": true,
"toolRestrictions": true
}
},
"triggers": {
"keywords": [
"example-trigger-1",
"example-trigger-2"
],
"patterns": []
},
"tools": {
"allowed": [
"Read",
"Grep",
"Bash"
],
"restricted": []
},
"metadata": {
"author": "Plugin Author",
"category": "general",
"tags": []
}
}

View File

@@ -0,0 +1,68 @@
{
"_comment": "Mapping of error code prefixes to API modules/services. Used for determining the origin and handling strategy for different error types.",
"mappings": {
"AUTH": {
"_comment": "Authentication-related errors",
"module": "AuthenticationService",
"http_status_code": 401,
"description": "Errors related to user authentication, authorization, or session management.",
"handling_strategy": "Retry with re-authentication if possible, otherwise log and return a 401 Unauthorized error."
},
"USER": {
"_comment": "User management errors",
"module": "UserService",
"http_status_code": 400,
"description": "Errors related to user creation, modification, or deletion.",
"handling_strategy": "Return a 400 Bad Request error with specific details about the invalid user data or operation."
},
"PROD": {
"_comment": "Product catalog errors",
"module": "ProductCatalogService",
"http_status_code": 500,
"description": "Errors related to retrieving or managing product information.",
"handling_strategy": "Retry a limited number of times. If still failing, log the error and return a 500 Internal Server Error with a generic message. Monitor for widespread issues."
},
"ORD": {
"_comment": "Order processing errors",
"module": "OrderProcessingService",
"http_status_code": 409,
"description": "Errors related to order placement, modification, or fulfillment.",
"handling_strategy": "Return a 409 Conflict error if the order is in an invalid state. For other errors, attempt to automatically correct the order if possible, otherwise notify support and return a 500 Internal Server Error."
},
"PAY": {
"_comment": "Payment processing errors",
"module": "PaymentGatewayService",
"http_status_code": 402,
"description": "Errors related to payment authorization, capture, or refund.",
"handling_strategy": "Return a 402 Payment Required error. Provide specific instructions to the user on how to resolve the payment issue."
},
"RATE": {
"_comment": "Rate limiting errors",
"module": "RateLimiter",
"http_status_code": 429,
"description": "Errors indicating that the client has exceeded their rate limit.",
"handling_strategy": "Return a 429 Too Many Requests error with a 'Retry-After' header indicating when the client can retry."
},
"DATA": {
"_comment": "Data validation or database errors",
"module": "DatabaseService",
"http_status_code": 503,
"description": "Errors related to accessing or manipulating data in the database. Includes validation failures.",
"handling_strategy": "Retry database operations with exponential backoff. If persistent, return a 503 Service Unavailable error, indicating a temporary issue. Alert the database administrators."
},
"INTEG": {
"_comment": "Integration errors with external services",
"module": "IntegrationService",
"http_status_code": 502,
"description": "Errors encountered when communicating with external APIs or services.",
"handling_strategy": "Implement circuit breaker pattern to prevent cascading failures. Return a 502 Bad Gateway error if the external service is unavailable."
},
"NOTF": {
"_comment": "Notification service errors",
"module": "NotificationService",
"http_status_code": 500,
"description": "Errors related to sending emails, SMS messages, or push notifications.",
"handling_strategy": "Queue failed notifications for retry. Log errors and monitor for persistent failures. Return a 500 Internal Server Error to the client, indicating a temporary issue with notifications."
}
}
}

View File

@@ -0,0 +1,56 @@
{
"_comment": "Template for a standardized error response.",
"error": {
"_comment": "Top-level key indicating an error occurred.",
"code": "ERR_INVALID_INPUT",
"_comment": "A unique error code for programmatic handling. Should be stable and not change even if the message changes.",
"message": "Invalid input provided.",
"_comment": "A human-readable error message. Should be helpful to the user.",
"status": 400,
"_comment": "The HTTP status code associated with the error.",
"details": {
"_comment": "Optional details about the error. Can be an object or an array.",
"field": "email",
"issue": "Email address is not valid."
},
"timestamp": "2024-10-27T10:00:00Z",
"_comment": "Timestamp of when the error occurred (ISO 8601 format)."
},
"_comment": "Example of a different error scenario (Internal Server Error)",
"example_internal_server_error": {
"error": {
"code": "ERR_INTERNAL_SERVER_ERROR",
"message": "An unexpected error occurred on the server.",
"status": 500,
"details": {
"_comment": "This can be omitted or contain sensitive information that should not be exposed to the client.",
"errorId": "a1b2c3d4e5f6g7h8"
},
"timestamp": "2024-10-27T10:01:00Z"
}
},
"_comment": "Example of a different error scenario (Unauthorized)",
"example_unauthorized": {
"error": {
"code": "ERR_UNAUTHORIZED",
"message": "Unauthorized: Invalid credentials.",
"status": 401,
"details": null,
"_comment": "Details are often omitted for unauthorized errors.",
"timestamp": "2024-10-27T10:02:00Z"
}
},
"_comment": "Example of a different error scenario (Not Found)",
"example_not_found": {
"error": {
"code": "ERR_NOT_FOUND",
"message": "Resource not found.",
"status": 404,
"details": {
"resource": "user",
"id": "123"
},
"timestamp": "2024-10-27T10:03:00Z"
}
}
}

View File

@@ -0,0 +1,28 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Claude Skill Configuration",
"type": "object",
"required": ["name", "description"],
"properties": {
"name": {
"type": "string",
"pattern": "^[a-z0-9-]+$",
"maxLength": 64,
"description": "Skill identifier (lowercase, hyphens only)"
},
"description": {
"type": "string",
"maxLength": 1024,
"description": "What the skill does and when to use it"
},
"allowed-tools": {
"type": "string",
"description": "Comma-separated list of allowed tools"
},
"version": {
"type": "string",
"pattern": "^\\d+\\.\\d+\\.\\d+$",
"description": "Semantic version (x.y.z)"
}
}
}

View File

@@ -0,0 +1,27 @@
{
"testCases": [
{
"name": "Basic activation test",
"input": "trigger phrase example",
"expected": {
"activated": true,
"toolsUsed": ["Read", "Grep"],
"success": true
}
},
{
"name": "Complex workflow test",
"input": "multi-step trigger example",
"expected": {
"activated": true,
"steps": 3,
"toolsUsed": ["Read", "Write", "Bash"],
"success": true
}
}
],
"fixtures": {
"sampleInput": "example data",
"expectedOutput": "processed result"
}
}

View File

@@ -0,0 +1,7 @@
# References
Bundled resources for api-error-handler skill
- [ ] http_status_codes.md: A comprehensive list of HTTP status codes with descriptions and when to use them.
- [ ] error_handling_best_practices.md: Best practices for API error handling, including security considerations.
- [ ] example_error_responses.json: Examples of well-structured error responses in JSON format.

View File

@@ -0,0 +1,69 @@
# Skill Best Practices
Guidelines for optimal skill usage and development.
## For Users
### Activation Best Practices
1. **Use Clear Trigger Phrases**
- Match phrases from skill description
- Be specific about intent
- Provide necessary context
2. **Provide Sufficient Context**
- Include relevant file paths
- Specify scope of analysis
- Mention any constraints
3. **Understand Tool Permissions**
- Check allowed-tools in frontmatter
- Know what the skill can/cannot do
- Request appropriate actions
### Workflow Optimization
- Start with simple requests
- Build up to complex workflows
- Verify each step before proceeding
- Use skill consistently for related tasks
## For Developers
### Skill Development Guidelines
1. **Clear Descriptions**
- Include explicit trigger phrases
- Document all capabilities
- Specify limitations
2. **Proper Tool Permissions**
- Use minimal necessary tools
- Document security implications
- Test with restricted tools
3. **Comprehensive Documentation**
- Provide usage examples
- Document common pitfalls
- Include troubleshooting guide
### Maintenance
- Keep version updated
- Test after tool updates
- Monitor user feedback
- Iterate on descriptions
## Performance Tips
- Scope skills to specific domains
- Avoid overlapping trigger phrases
- Keep descriptions under 1024 chars
- Test activation reliability
## Security Considerations
- Never include secrets in skill files
- Validate all inputs
- Use read-only tools when possible
- Document security requirements

View File

@@ -0,0 +1,70 @@
# Skill Usage Examples
This document provides practical examples of how to use this skill effectively.
## Basic Usage
### Example 1: Simple Activation
**User Request:**
```
[Describe trigger phrase here]
```
**Skill Response:**
1. Analyzes the request
2. Performs the required action
3. Returns results
### Example 2: Complex Workflow
**User Request:**
```
[Describe complex scenario]
```
**Workflow:**
1. Step 1: Initial analysis
2. Step 2: Data processing
3. Step 3: Result generation
4. Step 4: Validation
## Advanced Patterns
### Pattern 1: Chaining Operations
Combine this skill with other tools:
```
Step 1: Use this skill for [purpose]
Step 2: Chain with [other tool]
Step 3: Finalize with [action]
```
### Pattern 2: Error Handling
If issues occur:
- Check trigger phrase matches
- Verify context is available
- Review allowed-tools permissions
## Tips & Best Practices
- ✅ Be specific with trigger phrases
- ✅ Provide necessary context
- ✅ Check tool permissions match needs
- ❌ Avoid vague requests
- ❌ Don't mix unrelated tasks
## Common Issues
**Issue:** Skill doesn't activate
**Solution:** Use exact trigger phrases from description
**Issue:** Unexpected results
**Solution:** Check input format and context
## See Also
- Main SKILL.md for full documentation
- scripts/ for automation helpers
- assets/ for configuration examples

View File

@@ -0,0 +1,7 @@
# Scripts
Bundled resources for api-error-handler skill
- [ ] validate_status_code.py: Validates if a given HTTP status code is valid according to standards.
- [ ] format_error_response.py: Formats an error response into a consistent JSON structure.
- [ ] generate_error_code.py: Generates a unique error code for internal tracking.

View File

@@ -0,0 +1,42 @@
#!/bin/bash
# Helper script template for skill automation
# Customize this for your skill's specific needs
set -e
function show_usage() {
echo "Usage: $0 [options]"
echo ""
echo "Options:"
echo " -h, --help Show this help message"
echo " -v, --verbose Enable verbose output"
echo ""
}
# Parse arguments
VERBOSE=false
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_usage
exit 0
;;
-v|--verbose)
VERBOSE=true
shift
;;
*)
echo "Unknown option: $1"
show_usage
exit 1
;;
esac
done
# Your skill logic here
if [ "$VERBOSE" = true ]; then
echo "Running skill automation..."
fi
echo "✅ Complete"

View File

@@ -0,0 +1,32 @@
#!/bin/bash
# Skill validation helper
# Validates skill activation and functionality
set -e
echo "🔍 Validating skill..."
# Check if SKILL.md exists
if [ ! -f "../SKILL.md" ]; then
echo "❌ Error: SKILL.md not found"
exit 1
fi
# Validate frontmatter
if ! grep -q "^---$" "../SKILL.md"; then
echo "❌ Error: No frontmatter found"
exit 1
fi
# Check required fields
if ! grep -q "^name:" "../SKILL.md"; then
echo "❌ Error: Missing 'name' field"
exit 1
fi
if ! grep -q "^description:" "../SKILL.md"; then
echo "❌ Error: Missing 'description' field"
exit 1
fi
echo "✅ Skill validation passed"