AgentSkillsCN

async-and-errors

后端服务的异步模式与错误处理规范。关键词:异步、错误处理、Promise、领域错误、错误边界。

SKILL.md
--- frontmatter
name: async-and-errors
description: "Async patterns and error-handling conventions for backend services. Keywords: async, error handling, promises, domain errors, error boundary."

Async and Errors

This skill describes pragmatic patterns for async flows and error handling in backend services.


1. Core rules

  1. Do not swallow errors: either handle them or propagate them.
  2. Catch once per layer: avoid repeated catch-and-rethrow without adding value.
  3. Make failures observable: capture exceptions to monitoring (with safe context).
  4. Prefer typed domain errors: map to HTTP responses in controllers.

2. Async route handlers (Express-style)

Avoid unhandled promise rejections by using an async wrapper:

ts
export function asyncHandler(fn) {
  return (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);
}

router.post("/users", asyncHandler(async (req, res) => {
  // ...
}));

Register an error boundary after routes:

ts
app.use("/api", routes);
app.use(errorBoundary);

3. Domain errors (recommended)

Define typed errors for common cases:

ts
export class NotFoundError extends Error {}
export class ConflictError extends Error {}
export class ForbiddenError extends Error {}

Controllers translate domain errors into status codes:

  • NotFoundError → 404
  • ConflictError → 409
  • ForbiddenError → 403

Unexpected errors → 500 (and captured to monitoring).


4. Error boundary pattern

An error boundary should:

  • capture the error (with safe tags/context)
  • return a consistent response shape
ts
export function errorBoundary(err, req, res, _next) {
  monitor.captureException(err, {
    tags: { layer: "http", route: req.path, method: req.method },
  });
  res.status(500).json({ error: "Internal server error" });
}

Related Skills

  • routing-and-controllers
  • sentry-and-monitoring (in repo/)