Skip to content

Throwing a non-Error crashes the runner and takes down the whole run #183

Description

@DmitrySharabin

Code that throws a non-Error cannot be tested with hTest: the runner itself crashes, and the whole run goes down with it — not just the offending test.

Reproduction

package.json

{ "type": "module" }

t.js

export default { tests: [{ run: () => { throw "boom"; }, throws: true }] };
npx htest t.js --ci

Expected: ✅ 1/1 PASS — throws: true says any throw satisfies the test.

Actual:

TypeError: Cannot use 'in' operator to search for 'actual' in boom

The process dies, so every other test file in the run is lost too.

Cause

if ("actual" in e) {

in throws a TypeError when its right operand is not an object, so duck-typing the caught value crashes on any primitive.

Scope

Every primitive throw, with or without throws: true:

Thrown value Result
"boom" ❌ Cannot use 'in' operator … in boom
42 ❌ Cannot use 'in' operator … in 42
null ❌ Cannot use 'in' operator … in null
undefined ❌ Cannot use 'in' operator … in undefined
new Error("boom") ✅ works

throws: true, throws: "boom" and a predicate are all unreachable — the crash happens before any of them is consulted.

Notes

Throwing a string is legal JS and shows up in real code (some libraries and older APIs reject with strings). Guarding the duck-type check would let those tests run and, more importantly, keep one bad test from taking down the run.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions