Blyp Docs

createError()

Use createError() when you want to throw a structured BlypError instead of a plain Error.

It is the right fit when you need:

Basic example

import { createError } from "@blyp/core";

throw createError({
  status: 402,
  code: "PAYMENT_DECLINED",
  message: "Payment failed",
  why: "Card declined by issuer",
  fix: "Try a different payment method",
  link: "https://docs.example.com/payments/declined",
  details: { paymentId: "pay_123" },
});

What Blyp logs when the error is caught:

[ERROR] Payment failed
  status=402 code=PAYMENT_DECLINED type=BlypError

What the HTTP response body looks like:

{
  "status": 402,
  "code": "PAYMENT_DECLINED",
  "message": "Payment failed",
  "why": "Card declined by issuer",
  "fix": "Try a different payment method",
  "link": "https://docs.example.com/payments/declined",
  "details": {
    "paymentId": "pay_123"
  }
}

What it gives you

Logging behavior

By default:

You can override or suppress that behavior.

const error = createError({
  status: 404,
  message: "User not found",
  skipLogging: true,
});

return Response.json(error.toJSON(), { status: error.status });
const error = createError({
  status: 503,
  message: "Primary database unavailable",
  logLevel: "warning",
  logger: request.blypLog,
});

Common use cases

API validation failures

if (!body.email) {
  throw createError({
    status: 400,
    code: "EMAIL_REQUIRED",
    message: "Email is required",
    fix: "Pass email in the request body",
  });
}

Permission checks

if (!session.isAdmin) {
  throw createError({
    status: 403,
    code: "ADMIN_REQUIRED",
    message: "You do not have access to this resource",
    why: "The current session lacks the admin role",
  });
}

Wrapping downstream failures

try {
  await payments.charge(input);
} catch (cause) {
  throw createError({
    status: 502,
    code: "PAYMENTS_UPSTREAM_FAILED",
    message: "Payment provider request failed",
    why: "The upstream provider returned an unexpected failure",
    details: { cause },
  });
}

Pair it with HTTP_CODES

If you repeat the same error shape in multiple places, promote it to a reusable preset with HTTP Codes instead of repeating createError() calls inline.

import { HTTP_CODES } from "@blyp/core";

const INVALID_COUPON = HTTP_CODES.BAD_REQUEST.extend({
  code: "INVALID_COUPON",
  message: "Coupon code is invalid",
  why: "The supplied coupon does not exist or has expired",
  fix: "Check the code or request a new promotion link",
});

throw INVALID_COUPON.create({
  details: {
    coupon: body.coupon,
  },
});

Use direct createError() calls for one-off failures, and HTTP_CODES.<STATUS>.extend(...) when the same error contract should be shared across handlers or services.