From 6f653d27ae7ddb4df519f7dc64dd4230e568fecf Mon Sep 17 00:00:00 2001 From: guoyangzhen Date: Wed, 18 Mar 2026 16:45:12 +0800 Subject: [PATCH] fix: ctx.assert() throws HttpError instances Wrap http-assert to re-throw errors using koa's own http-errors, so instanceof HttpError checks work correctly. Fixes #1925 --- lib/context.js | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/context.js b/lib/context.js index 68ffe3482..058093f62 100644 --- a/lib/context.js +++ b/lib/context.js @@ -6,6 +6,7 @@ const util = require('util') const createError = require('http-errors') +const { HttpError } = require('http-errors') const httpAssert = require('http-assert') const delegate = require('delegates') const statuses = require('statuses') @@ -13,6 +14,29 @@ const Cookies = require('cookies') const COOKIES = Symbol('context#cookies') +// Wrap http-assert to ensure thrown errors are instances of koa's HttpError. +// http-assert uses its own http-errors dependency, so instanceof checks fail. +// See: https://github.com/koajs/koa/issues/1925 +function wrappedAssert (value, status, msg, opts) { + try { + httpAssert(value, status, msg, opts) + } catch (err) { + if (err instanceof HttpError) { + throw err + } + // Re-throw using koa's createError so instanceof HttpError works + throw createError(err.status || err.statusCode || 500, err.message || msg, opts) + } +} + +wrappedAssert.fail = httpAssert.fail +wrappedAssert.equal = httpAssert.equal +wrappedAssert.notEqual = httpAssert.notEqual +wrappedAssert.ok = httpAssert.ok +wrappedAssert.strictEqual = httpAssert.strictEqual +wrappedAssert.notStrictEqual = httpAssert.notStrictEqual +wrappedAssert.deepEqual = httpAssert.deepEqual + /** * Context prototype. */ @@ -69,7 +93,7 @@ const proto = module.exports = { * @api public */ - assert: httpAssert, + assert: wrappedAssert, /** * Throw an error with `status` (default 500) and