# Prompting For Error Handling That Is Not Just try/catch

> Named error classes, correlation IDs, and a rule about what never reaches the client.

- **Author:** [Budi Santoso (@budi_santoso)](https://www.promptabide.com/budi_santoso)
- **Published:** 2026-07-23
- **Updated:** 2026-08-22
- **Tags:** `backend`, `node`, `error-handling`, `reliability`
- **Views:** 9310
- **Likes:** 219

## Prompt

```
Ask for "error handling" and you get try/catch wrapped around everything with console.log in the catch. Ask for this instead:

"Add error handling to this module. Requirements:
- A small hierarchy: AppError base, then ValidationError, NotFoundError, ConflictError, ExternalServiceError
- Each carries an HTTP status and a machine-readable code
- One central Express error middleware maps them to responses
- Unknown errors become a 500 with a correlation ID; the real message goes to the logger, never to the client
- Stack traces only when NODE_ENV !== production
- External calls get a timeout and one retry with backoff; a retry exhaustion is an ExternalServiceError, not a 500"

The line that earns its place is "the real message goes to the logger, never to the client". Without it you leak table names in 500 bodies.
```

## Output

*Produced by Claude · claude-opus-4.*

```
export class ConflictError extends AppError {
  constructor(message: string, code = "CONFLICT") {
    super(message, 409, code)
  }
}

// error middleware
if (err instanceof AppError) {
  return res.status(err.status).json({ success: false, code: err.code, message: err.message })
}
const correlationId = randomUUID()
logger.error({ correlationId, err })
return res.status(500).json({ success: false, code: "INTERNAL", correlationId })
```

---

Canonical HTML: https://www.promptabide.com/bides/prompt-real-error-handling-budi-santoso-3
Agent guide: https://www.promptabide.com/llms.txt · https://www.promptabide.com/agent-instructions.md
Sitemap: https://www.promptabide.com/sitemap.xml
