# Backend Error Handling

> NestJS error handling: handleException, CustomHttpException, AllExceptionsFilter, PrismaExceptionFilter, response helpers sendSuccessfulResponse and sendCustomResponse. Use when handling errors, API responses, or exception filters.

- Skill: `xmuhameed/backend-error-handling` (Agent Skill)
- Install (CLI): `npx skillmds@latest add xmuhameed/backend-error-handling`
- Raw SKILL.md: https://api.skillmd.com/api/skills/xmuhameed/backend-error-handling/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: xmuhameed (https://skillmd.com/u/xmuhameed)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/xmuhameed/backend-error-handling

---


# Backend Error Handling

## Service Pattern

```typescript
async getById(id: string) {
  try {
    const item = await this.prisma.feature.findUnique({ where: { id } });
    if (!item) throw new CustomHttpException('Not found', HttpStatus.NOT_FOUND);
    return item;
  } catch (error) {
    handleException(error, false, {});
  }
}
```

Every public service method uses `try/catch` → `handleException`.

## Throw Business Errors

```typescript
throw new CustomHttpException('Slug already exists', HttpStatus.BAD_REQUEST);
throw new CustomHttpException('Not found', HttpStatus.NOT_FOUND);
throw new CustomForbiddenException('Must be admin');
```

## Response Helpers

```typescript
// Single entity
return sendSuccessfulResponse(data);
// → { status: 'success', data }

// List with count
return sendCustomResponse({ data: requests, count });
// → { status: 'success', data, count }

// Custom fields
return sendCustomResponse({ data, count, types });
```

**Never** return raw Prisma objects from controllers.

## Global Filters

Register **once** in `app.module.ts`:

```typescript
{ provide: APP_FILTER, useClass: AllExceptionsFilter },
{ provide: APP_FILTER, useClass: PrismaExceptionFilter },
```

| Filter | Handles |
|--------|---------|
| `AllExceptionsFilter` | HttpException → log → handleException |
| `PrismaExceptionFilter` | P2002 unique, P2025 not found → `{ data: { errorMessage } }` |

## Error Response Shapes

| Type | Shape |
|------|-------|
| Business | `{ status: 'error', key, data }` |
| Prisma | `{ data: { errorMessage, errorTarget? } }` |
| Database P2002 | key: `SOMETHING_WENT_WRONG_DATABASE_P2002` |

## Custom Exceptions

`CustomHttpException`, `CustomBadRequestException`, `CustomNotFoundException`, `CustomForbiddenException` — flag `customError: true` skips verbose logging.

## Logging

File logs in `logs/` — daily rotation. `LoggingInterceptor` for request timing. Uncaught → `logs/uncaughtException.txt`.

