Global Error Handling
Your approach to handling global error handling. Use this skill when working on files where global error handling comes into play.
Best use case
Global Error Handling is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Your approach to handling global error handling. Use this skill when working on files where global error handling comes into play.
Teams using Global 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/global-error-handling/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How Global Error Handling Compares
| Feature / Agent | Global 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?
Your approach to handling global error handling. Use this skill when working on files where global error handling comes into play.
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
# Global Error Handling
This Skill provides Claude Code with specific guidance on how to handle errors consistently across the MorrisB application.
## CRITICAL: Always Follow This Pattern
When writing or modifying any backend route, service, or middleware, you MUST use the custom error handling system.
## Error Classes Available
Import errors from `../errors` (adjust path as needed):
```typescript
import {
// Error classes
AppError,
ValidationError,
UnauthorizedError,
ForbiddenError,
NotFoundError,
ConflictError,
RateLimitError,
InternalError,
ExternalServiceError,
// Async handler wrapper
asyncHandler,
asyncAuthHandler,
} from "../errors";
```
## Route Handler Pattern (REQUIRED)
### Option 1: asyncHandler Wrapper (Preferred)
Use `asyncHandler` or `asyncAuthHandler` to automatically catch errors:
```typescript
import { asyncAuthHandler, NotFoundError, ForbiddenError } from "../errors";
router.get("/:workspaceId/contacts/:id", authenticate, asyncAuthHandler(async (req, res) => {
const { workspaceId, id } = req.params;
const userId = req.user?._id?.toString();
// Validate workspace access - throws ForbiddenError
const workspace = await Project.findById(workspaceId);
if (!workspace) {
throw NotFoundError.workspace(workspaceId);
}
if (workspace.userId.toString() !== userId) {
throw ForbiddenError.workspaceAccess();
}
// Find contact - throws NotFoundError
const contact = await Contact.findOne({ _id: id, workspaceId });
if (!contact) {
throw NotFoundError.contact(id);
}
res.json({ success: true, data: { contact } });
}));
```
### Option 2: Traditional try/catch (Use sparingly)
Only use try/catch when you need specific error handling:
```typescript
router.post("/register", async (req, res, next) => {
try {
const validatedData = registerSchema.parse(req.body);
// ... logic
} catch (error: any) {
if (error.name === "ZodError") {
return next(ValidationError.fromZod(error));
}
next(error); // Pass to global error handler
}
});
```
## Error Factory Methods
Use static factory methods for common error scenarios:
### ValidationError
```typescript
throw ValidationError.missingField("email");
throw ValidationError.invalidFormat("phone", "+1-XXX-XXX-XXXX");
throw ValidationError.invalidId("contact");
throw ValidationError.fromZod(zodError);
```
### UnauthorizedError
```typescript
throw UnauthorizedError.noToken();
throw UnauthorizedError.invalidToken();
throw UnauthorizedError.tokenExpired();
throw UnauthorizedError.invalidCredentials();
```
### ForbiddenError
```typescript
throw ForbiddenError.emailNotVerified();
throw ForbiddenError.workspaceAccess();
throw ForbiddenError.insufficientPermissions("delete contacts");
```
### NotFoundError
```typescript
throw NotFoundError.workspace(workspaceId);
throw NotFoundError.contact(contactId);
throw NotFoundError.user(userId);
throw NotFoundError.campaign(campaignId);
throw NotFoundError.sequence(sequenceId);
throw new NotFoundError("Custom Resource", identifier);
```
### ConflictError
```typescript
throw ConflictError.emailExists();
throw ConflictError.duplicate("Contact", "email", "user@example.com");
```
### ExternalServiceError
```typescript
throw ExternalServiceError.email("Failed to send verification email");
throw ExternalServiceError.ai("OpenAI rate limit exceeded");
```
## DO NOT DO THIS
❌ **Never manually send error responses in routes:**
```typescript
// BAD - Don't do this
res.status(404).json({
success: false,
error: "Contact not found",
});
```
❌ **Never catch and swallow errors silently:**
```typescript
// BAD - Don't do this
try {
await someOperation();
} catch (error) {
console.error(error); // Lost error!
}
```
❌ **Never use generic error messages:**
```typescript
// BAD - Not helpful
throw new Error("Something went wrong");
```
## DO THIS INSTEAD
✅ **Throw specific error classes:**
```typescript
// GOOD
throw NotFoundError.contact(contactId);
```
✅ **Use asyncHandler to auto-catch:**
```typescript
// GOOD - Errors automatically passed to global handler
router.get("/", asyncHandler(async (req, res) => {
// If this throws, global handler catches it
const data = await getData();
res.json({ success: true, data });
}));
```
✅ **Pass errors to next() when in try/catch:**
```typescript
// GOOD - Passes to global error handler
} catch (error) {
next(error);
}
```
## Server Setup Required
The global error handler must be registered in `server.ts`:
```typescript
import { globalErrorHandler, notFoundHandler } from "./middleware/errorHandler";
// After all routes
app.use(notFoundHandler);
app.use(globalErrorHandler);
```
## Error Response Format
All errors are returned in this consistent format:
```json
{
"success": false,
"error": {
"message": "Contact not found",
"code": "RES_001",
"details": {
"resource": "Contact",
"identifier": "123abc"
}
}
}
```
## Best Practices Summary
1. **Always use asyncHandler/asyncAuthHandler** for async route handlers
2. **Always throw specific error classes** instead of generic Error
3. **Always use factory methods** when available (e.g., `NotFoundError.contact()`)
4. **Never manually send error responses** - let the global handler do it
5. **Pass errors to next()** if you catch them locally
6. **Use logger for debugging**, not console.log
7. **Include helpful details** in error constructors for debugging
## File References
- Error classes: `backend/src/errors/AppError.ts`
- Error handler middleware: `backend/src/middleware/errorHandler.ts`
- Index exports: `backend/src/errors/index.ts`Related Skills
implementing-error-handling
Master error handling patterns across languages including exceptions, Result types, error propagation, and graceful degradation to build resilient applications. Use when implementing error handling, designing APIs, or improving application reliability.
golang-error-handling
Go error handling review. Use when checking error wrapping, context propagation, or error checking patterns. Ensures proper error chains, context usage, and nil checks.
global-standards
Project-wide coding standards and conventions specialist. Use PROACTIVELY when writing code, making architectural decisions, or establishing project conventions. Covers coding style, commenting, error handling, validation, tech stack consistency, and project conventions across all languages and frameworks.
global-methylation-profile
This skill performs genome-wide DNA methylation profiling. It supports single-sample and multi-sample workflows to compute methylation density distributions, genomic feature distribution of the methylation profile, and sample-level clustering/PCA. Use it when you want to systematically characterize global methylation patterns from WGBS or similar per-CpG methylation call files.
Fundamental Attribution Error
Over-attributing others' behavior to their character while under-weighting situational factors that shape their actions
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.
fix-validation-errors-with-overlays
Use when you have lint errors but can't modify the source spec, or need to add missing descriptions/tags via overlay
error-tracking
Add error tracking and performance monitoring to your project services. Use this skill when adding error handling, creating new controllers/routes, instrumenting background jobs, or tracking performance. Supports Sentry, Datadog, and other monitoring solutions. ALL ERRORS MUST BE CAPTURED - no exceptions.
error-root-analyzer
Comprehensive error analysis and root cause resolution. Use when programs fail, crash, or produce errors during execution. This skill performs deep debugging by identifying root causes (not just surface-level symptoms), conducting thorough module reviews to uncover related bugs and exceptions, and implementing holistic fixes that address all discovered issues.
error-handling
Comprehensive error handling patterns for Splits Network services and apps
error-handling-patterns
Master error handling patterns across languages including exceptions, Result types, error propagation, and graceful degradation to build resilient applications. Use when implementing error handling, designing APIs, or improving application reliability.
error-diagnostics-error-analysis
You are an expert error analysis specialist with deep expertise in debugging distributed systems, analyzing production incidents, and implementing comprehensive observability solutions.