Skip to content

Andrewpai/application create - #57

Merged
andrewpai merged 41 commits into
nextfrom
andrewpai/application-create
Oct 7, 2026
Merged

andrewpai merged 41 commits into
nextfrom
andrewpai/application-create

Conversation

@andrewpai

Copy link
Copy Markdown
Contributor

New application:create command to create an application in one of a few standard forms. Also supports --data for passing a JSON application definition to the API for full custom control.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Global CORS mutation lacks required confirmation, and several command correctness issues remain.

Review effort: Balanced
Findings: 5 Medium severity · 4 Low severity

Open (9)
What changed in this PR

Adds application:create with standard security profiles and custom JSON configuration, alongside CLI safety, automation, documentation, and test improvements.

Changes:

  • Adds application creation with profile defaults, CORS configuration, and custom JSON support.
  • Improves kickstart confirmation, unattended installation, and option naming.
  • Expands unit/integration coverage and supporting documentation.
File Description
src/​utils.ts Adds reusable confirmation handling.
src/​index.ts Formatting-only change.
src/​commands/​kickstart-kill.ts Adds --yes confirmation flow.
src/​commands/​kickstart-install.ts Adds unattended installation options and validation.
src/​commands/​index.ts Exports the new command.
src/​commands/​import-generate.ts Adds kebab-case options and deprecated aliases.
src/​commands/​application-create.ts Implements application creation.
package.json Updates version and test scripts.
package-lock.json Synchronizes package version.
CONTRIBUTING.md Documents contribution and testing policies.
AGENTS.md Expands CLI and safety guidance.
__tests__/​utils.test.js Tests confirmation utilities.
__tests__/​telemetry/​telemetry.test.js Mocks telemetry requests.
__tests__/​integration/​setup.js Extends integration infrastructure.
__tests__/​integration/​application-create/​application-create.integration.test.js Tests application creation against FusionAuth.
__tests__/​commands/​kickstart-kill.test.js Tests destructive-operation gating.
__tests__/​commands/​kickstart-install.test.js Tests installation options and validation.
__tests__/​commands/​import-generate.test.js Tests renamed and deprecated options.
__tests__/​commands/​application-create.test.js Tests application profiles, data, CORS, and output.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread __tests__/integration/setup.js Outdated
Comment thread src/commands/application-create.ts
Comment thread src/commands/application-create.ts Outdated
Comment thread src/commands/application-create.ts
Comment thread src/commands/kickstart-install.ts Outdated
Comment thread src/commands/application-create.ts Outdated
Comment thread src/commands/import-generate.ts Outdated
Comment thread src/commands/kickstart-install.ts Outdated
Comment thread src/commands/kickstart-install.ts Outdated
Copilot AI balanced review requested due to automatic review settings September 30, 2026 17:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/commands/application-create.ts
Copilot AI balanced review requested due to automatic review settings September 30, 2026 17:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Global CORS changes lack required confirmation, while tenant targeting, origin configuration, validation, and macOS readiness contain functional defects.

Review effort: Balanced
Findings: 1 High severity · 5 Medium severity · 1 Low severity

Open (7)
Previously missed (2)

In code that hasn't changed since last review

Medium severity Apply authorized origins to system CORS configuration

src/​commands/​application-create.ts:238

--authorized-origin-url is advertised as CORS configuration, but this only writes the application's OAuth authorizedOriginURLs. ensureCorsHeaders() updates global allowedHeaders and enabled, never corsConfiguration.allowedOrigins, so browser requests from a newly supplied origin remain blocked unless it was already configured separately. Merge these origins into system CORS (with deduplication) or change the option's contract.

Medium severity Honor tenant ID supplied in application data

src/​commands/​application-create.ts:254

Honor a tenant supplied inside --data. The help says --tenant-id overrides --data, but the client receives only the flag value; without the flag, no tenant header is sent and multi-tenant FusionAuth instances may reject the request or target the API key's default tenant even when application.tenantId is present.

Copilot AI balanced review requested due to automatic review settings September 30, 2026 19:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Global CORS changes lack required confirmation, and several command and integration behaviors can produce incorrect results.

Review effort: Balanced
Findings: 1 High severity · 4 Medium severity

Open (5)
Resolved since last review (2)

Copilot AI balanced review requested due to automatic review settings September 30, 2026 19:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Invalid custom payloads, tenant scoping, misleading errors, and an unstopped failure-path spinner need correction.

Review effort: Balanced
Findings: 2 High severity · 1 Medium severity

Open (3)
Resolved since last review (5)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Validate parsed JSON is a non-null object

src/​commands/​application-create.ts:199

JSON.parse may return null, an array, or a scalar, but the cast accepts all of them as Application. For example, --data null then crashes at application.id, while arrays/scalars can be sent as malformed API payloads. Validate that the parsed value is a non-null, non-array object and return a clear input error before applying overrides.

Comment thread src/commands/application-create.ts
Comment thread src/commands/kickstart-install.ts
Comment thread src/commands/application-create.ts Outdated
mark-robustelli and others added 15 commits September 30, 2026 15:24
- import-generate: detect deprecated flags in --flag=value form, not just bare --flag
- kickstart-install: replace setTimeout-chained install steps with sequential
  awaited steps so errors propagate through try/catch and ordering is
  deterministic; also await createKickstart (was previously fire-and-forget)
- utils: confirmOrExit now requires both stdin and stdout to be TTYs before
  treating the session as interactive, and normalizes confirmation input
  (trims whitespace, accepts y/yes case-insensitively)
- utils.ts: extract isConfirmationAccepted() as a pure, exported function so
  the accept/reject decision logic can be unit tested directly without
  simulating a real TTY
- kickstart-kill.ts: export action() and add an injectable deps parameter
  (isDockerInstalled, confirmOrExit, spawn) so tests can exercise the
  confirmation gating without touching real docker or exiting the process
- add __tests__/utils.test.js covering isConfirmationAccepted and the
  yes-bypass / non-interactive TTY-detection paths of confirmOrExit
- add __tests__/commands/kickstart-kill.test.js covering docker-not-installed,
  CLI_DIR mismatch, --yes bypass, and confirm-rejected gating paths
- wire both new test files into the test and test:unit npm scripts
- extract getDeprecatedFlagUsage(argv) as a pure, exported function so the
  deprecation-detection logic is testable without mocking process.argv or
  console.warn
- export DEPRECATED_FLAGS for use in tests
- add __tests__/commands/import-generate.test.js covering: no deprecated
  flags used, bare --flag and --flag=value forms detected, multiple
  deprecated flags detected together, new kebab-case form not flagged,
  and that both the deprecated and current flag spellings populate the
  same underlying Commander option property
- wire the new test file into the test and test:unit npm scripts
…matical agreement'

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…xecuteApplicationCreate'

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
- Fix inverted localhost/container-IP fallback order in integration
  test setup's auth-readiness check
- Gate CORS system-configuration mutation behind --yes/confirmOrExit
  per the Risky Operations Policy
- Make --name optional; required only for --profile, preserved from
  --data JSON unless explicitly overridden
- Document that applicationId/clientId are intentionally identical
  (FusionAuth never accepts clientId as input)
- Remove NODE_ENV-conditional exit from executeApplicationCreate so
  it always returns a result per its documented contract; thread the
  raw error through to the CLI wrapper for field-level error detail
@andrewpai

Copy link
Copy Markdown
Contributor Author

Re: "Test the dist resources path in addition to the source fallback" (kickstart-install.test.js:354, previously-missed finding, no dedicated inline thread).

Confirmed — this test always imports src/commands/kickstart-install.js via tsx, so __dirname was fixed to .../src/commands for the whole run. I verified directly that calling the function from that import only ever exercised the src-fallback branch; the dist-layout branch (and the error-throw path) had zero coverage despite the comment's claim.

Fixed in 1bd1254: added an injectable baseDir parameter to resolveResourcesDir() (defaulting to the real __dirname, so production behavior is unchanged), and replaced the old test with 4 synthetic temp-directory tests covering all three logic branches (dist found / src fallback found / neither found, including the previously-untested throw path). Also added a separate test that imports the real compiled dist/commands/kickstart-install.js directly and verifies it resolves correctly against the actual build output — this one skips gracefully (not fails) if dist/ hasn't been built yet, so test:unit still works without requiring a build first, while still being meaningful in CI (which always builds before testing).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The bridge-IP fallback depends on a generated Docker container name that is not stable across Compose project configurations.

Review effort: Balanced
Findings: None

Previously missed (1)

In code that hasn't changed since last review

Medium severity Resolve FusionAuth container ID via Compose instead of generated name

__tests__/​integration/​setup.js:24

This fallback relies on Docker Compose's generated container name, but the compose file does not declare container_name; the name changes when the project name is overridden (for example with COMPOSE_PROJECT_NAME). In that case both docker inspect calls silently fail and URL resolution falls back to localhost, defeating the new bridge-IP fallback. Resolve the fusionauth service container ID via docker compose ps -q fusionauth and inspect that ID in both lookup paths instead of hard-coding the generated name.

Two previously-missed findings from the same review, neither acted on
across two review cycles -- not a deliberate decision, just missed.

CONTAINER_NAME hard-coded Docker Compose's default generated container
name ('{project}-{service}-{index}'). If COMPOSE_PROJECT_NAME is set,
the real container name differs, both docker inspect calls silently
fail (caught by empty catch blocks), and the bridge-IP fallback this
PR added is defeated without any visible error. Replaced with
resolveContainerId(), which resolves the real ID via
`docker compose ps -q fusionauth`, independent of naming conventions.
Verified end-to-end via a full local docker-based integration run --
the bridge-IP fallback message still appears correctly, confirming
the dynamic resolution works.

COMPOSE_DIR used new URL(...).pathname, which leaves special characters
like spaces percent-encoded (e.g. '%20') rather than decoding them --
not a valid filesystem path component. Verified empirically that
fileURLToPath() correctly decodes it instead. Also replaced the
`cd ${COMPOSE_DIR} && ...` string-concatenation pattern (5 call sites)
with execAsync(cmd, { cwd: COMPOSE_DIR }), avoiding shell-quoting
issues with the path entirely rather than just moving them around.
Copilot AI balanced review requested due to automatic review settings October 2, 2026 15:55
@andrewpai

Copy link
Copy Markdown
Contributor Author

Re: "Resolve FusionAuth container ID via Compose instead of generated name" (setup.js:24, previously-missed finding, now recurring across two review cycles).

For transparency: this one was not a deliberate decision to skip — it was simply missed. It only ever surfaced as a summary-only "previously missed" bullet with no dedicated inline thread to reply to directly, and it slipped through across both rounds.

Confirmed the issue is real: CONTAINER_NAME hard-coded Compose's default generated name; if COMPOSE_PROJECT_NAME is set, the real name differs and both docker inspect calls silently fail, defeating the bridge-IP fallback with no visible error.

Fixed in da3659d: added resolveContainerId(), which resolves the real container ID via docker compose ps -q fusionauth instead of guessing the name. Verified end-to-end via a full local docker-based integration run — the bridge-IP fallback still engages correctly.

While investigating, I also found a second, closely related finding from the same review that was equally unaddressed ("Use fileURLToPath and cwd to support checkout paths containing spaces", setup.js:25) and fixed that in the same commit: COMPOSE_DIR now uses fileURLToPath() instead of .pathname (verified empirically that .pathname left spaces percent-encoded rather than decoding them), and all 5 cd ${COMPOSE_DIR} && ... call sites now use execAsync(cmd, { cwd: COMPOSE_DIR }) instead, avoiding shell-quoting issues with the path entirely.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Duplicate supplied origins can pollute global CORS configuration, and new resource tests leak temporary directories.

Review effort: Balanced
Findings: None

Previously missed (2)

In code that hasn't changed since last review

Medium severity Deduplicate authorized origins before updating CORS configuration

src/​commands/​application-create.ts:195

When --authorized-origin-url contains the same origin more than once, each copy passes this filter because it is compared only with the pre-existing allowlist. The patch then writes duplicate entries into the system-wide CORS configuration. Deduplicate the supplied origins before computing the additions.

Low severity Clean up temporary directories created by tests

__tests__/​commands/​kickstart-install.test.js:363

Each test in this block creates a directory under the system temp directory, but none of those directories are removed. Repeated local and CI runs therefore leave four directory trees behind per run; track them and clean them after each test.

Duplicate --authorized-origin-url values were only ever compared
against the pre-existing system CORS allowlist, not against each
other, so passing the same origin twice wrote a duplicate entry into
the system-wide CORS configuration. Deduped the supplied origins via
[...new Set(authorizedOrigins)] before filtering. Verified empirically
before/after, and added a regression test asserting the origin appears
exactly once in the PATCH payload.

Also fixed resolveResourcesDir()'s unit tests leaking temp directories
on every run -- mkTempDir() created a real directory under the OS temp
dir in each of the 4 tests but never removed any of them. Confirmed
this was a real, accumulating leak: found 16 leftover directories from
prior test runs still on disk. Now tracks created dirs and removes
them in afterEach; verified a fresh run leaves zero behind.
Copilot AI balanced review requested due to automatic review settings October 2, 2026 17:15
@andrewpai

Copy link
Copy Markdown
Contributor Author

Re: "Deduplicate authorized origins before updating CORS configuration" (application-create.ts:195, previously-missed finding, no dedicated inline thread).

Confirmed — authorizedOrigins was only ever compared against the pre-existing allowlist, not against itself, so passing the same --authorized-origin-url twice wrote a duplicate entry into the system-wide CORS configuration. Verified empirically before/after.

Fixed in d19dfc9: deduped via [...new Set(authorizedOrigins)] before filtering. Added a regression test asserting the origin appears exactly once in the PATCH payload.

@andrewpai

Copy link
Copy Markdown
Contributor Author

Re: "Clean up temporary directories created by tests" (kickstart-install.test.js:363, previously-missed finding, no dedicated inline thread).

Confirmed — none of the 4 resolveResourcesDir() tests cleaned up their mkTempDir()-created directories. Checked disk and found 16 leftover directories from prior test runs still present, confirming this was a real, accumulating leak.

Fixed in d19dfc9: mkTempDir() now tracks each created directory, and a new afterEach removes them. Cleaned up the 16 pre-existing leftovers and verified a fresh run leaves zero behind.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Repeated termination signals are ignored and can leave a hung teardown process impossible to stop normally.

Review effort: Balanced
Findings: None

Previously missed (1)

In code that hasn't changed since last review

Medium severity Exit immediately on repeated termination signals

__tests__/​integration/​setup.js:67

Because installing a signal handler disables Node's default termination behavior, returning on a second signal can make the test runner impossible to stop if the first docker compose down -v hangs. A repeated Ctrl+C/SIGTERM should exit immediately rather than being ignored.

Once a SIGINT/SIGTERM listener is registered, Node no longer applies
its default "a second Ctrl+C just kills the process" behavior on its
own -- the listener has full responsibility. The early `return` on a
repeated signal while handlingTerminationSignal was already true meant
that if forceTeardown()'s `docker compose down -v` call hung (it has
no timeout, unlike every other network call in this file), every
subsequent Ctrl+C/SIGTERM was silently swallowed, leaving no way to
interrupt the process short of `kill -9` from another terminal.

Verified both the bug and the fix with a standalone repro harness
simulating a permanently-hung teardown: the old logic left the process
running indefinitely after a second SIGINT; the new logic force-exits
with the expected code (130/143) immediately. Also ran the full
integration suite to confirm no regression in normal (non-hung)
teardown.
Copilot AI balanced review requested due to automatic review settings October 2, 2026 18:52
@andrewpai

Copy link
Copy Markdown
Contributor Author

Re: "Exit immediately on repeated termination signals" (setup.js:67, previously-missed finding, no dedicated inline thread).

Agreed, this is a real risk — confirmed it with a standalone repro harness simulating a permanently-hung forceTeardown() (which has no timeout on its docker compose down -v call, unlike every other network call in this file): with the old code, a second SIGINT after the first was silently swallowed and the process stayed stuck forever, with no way to interrupt it short of kill -9 from another terminal. Verified the fix resolves this — second signal now force-exits immediately with the expected code.

Fixed in 788aa00.

Note: deliberately not adding automated test coverage for this. Testing real process-level SIGINT/SIGTERM delivery and exit-code behavior from within the test suite itself is impractical with this project's existing test setup (these functions are private/unexported, and nothing else in this codebase attempts to test actual signal delivery) — verification here was done manually via an external repro harness instead, which is captured in this comment for the record.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The readiness loop performs potentially blocking Docker fallback discovery before testing the healthy localhost endpoint.

Review effort: Balanced
Findings: None

Previously missed (1)

In code that hasn't changed since last review

Medium severity Test localhost before slow Docker bridge resolution

__tests__/​integration/​setup.js:290

The bridge fallback is still resolved before localhost is tested: every iteration runs docker compose ps and docker inspect, then tries the URLs. A slow or hung Docker CLI can therefore block readiness even when the authenticated localhost endpoint is already healthy. Attempt localhost first and only resolve/inspect the container after that request fails or returns non-OK.

@andrewpai

Copy link
Copy Markdown
Contributor Author

Re: "Test localhost before slow Docker bridge resolution" (setup.js:290, previously-missed finding, no dedicated inline thread).

Reviewed this on the merits and are declining it.

This is an ordering nitpick on two cheap, local docker CLI calls (ps/inspect, normally tens of milliseconds) ahead of an HTTP fetch inside a loop that already has a 5-second per-attempt timeout and a 30-second total budget. Localhost is still tried and still wins the moment it's healthy — nothing here is silently incorrect, unlike the earlier (legitimate, fixed) bug where the bridge IP unconditionally overrode checkUrl and localhost was never actually reached at all. The theoretical "slow/hung Docker CLI blocks readiness" scenario this flags is true in the abstract but immaterial in practice given the existing timeout budget, and this exact file has already been restructured several times this session for real correctness/security findings.

At this point, flagging ordering of sub-50ms local subprocess calls inside an already-bounded retry loop as a "needs a closer look" item is past the point of being useful signal. Perfection is the enemy of done — this PR has been through extensive, substantive review across dozens of real findings (security validation gaps, CORS protocol correctness, resource leaks, signal handling), and this one does not clear the bar of being worth the risk of yet another change to already-well-tested timing-sensitive retry logic. Not acting on this.

@brob brob left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All in all, not setting off any alarm bells, LGTM with a couple output tweak suggestions

Need to add betaWarning() to the outputs, and add that they're in beta to the readmes and helps if we want this to be beta instead of just regular new functionality (i.e. making sure folks know this could go away or change)

Comment thread src/commands/application-create.ts
Comment thread src/commands/application-create.ts
Root cause: the FusionAuth SDK rejects with a ClientResponse instance,
which does NOT extend Error. All three wrapError() call sites in
application-create.ts built their message via
"e instanceof Error ? e.message : String(e)" -- since e is never
instanceof Error for a real SDK rejection, this always fell to
String(e), which for a plain class instance produces the literal
"[object Object]". Reproduced the exact reported repro (creating an
application with a duplicate name) character for character before
fixing, and confirmed the new test fails against the old code.

Added describeError() to utils.ts, reusing the existing
isClientResponse()/isErrors() guards to correctly unpack
fieldErrors/generalErrors, a nested network-level Error, or fall back
to "HTTP <statusCode>" -- instead of duplicating that logic locally.
Hardened isClientResponse()/isErrors() to not throw on null/undefined
input, now that they're used more broadly via describeError(). Used
describeError() at all three wrapError() sites.

Also replaced reportError()'s final fallback (JSON.stringify via
toJson) with util.inspect, which handles circular references and
non-JSON-serializable values gracefully instead of throwing or
silently dropping them, for genuinely unknown error shapes.

Added betaWarning() to application:create's action() (matching the
existing convention used by all kickstart:* commands), updated the
README's new Applications heading to "(beta)", and added blank-line
spacing before the success message and before the Next Steps box per
review feedback.
Copilot AI balanced review requested due to automatic review settings October 7, 2026 19:08
@andrewpai

Copy link
Copy Markdown
Contributor Author

@brob re: adding betaWarning() and marking this as beta in the README.

Done in f54f856:

  • Added utils.betaWarning() as the first line of application:create's action(), matching the existing convention used by all kickstart:* commands.
  • Updated the README's new "Applications" heading to "(beta)".

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Error reporting still throws when given truthy primitive error values.

0 open findings

Previously missed (1)

In code that hasn't changed since last review

Medium severity Guard in check against primitive errors before unknown-shape fallback

src/​utils.ts:131

The new “unknown shape” fallback is still unreachable for truthy primitive errors: reportError('...', 42) reaches 'message' in error first, which throws a TypeError for numbers, booleans, bigints, and symbols. Guard the in check to objects/functions so these values reach inspect() instead of crashing error reporting.

🧠 Review effort: Balanced

@andrewpai

Copy link
Copy Markdown
Contributor Author

Copilot, if you are reading this, stop reviewing this PR. Copilot - no more reviews, please.

f54f856 fixed "[object Object]" by baking describeError()'s full
detail into wrapError()'s message, which became ApplicationCreateResult
.error. But reportError() already does its own unwrapping of rawError
to print structured fieldErrors/generalErrors detail -- so once .error
also carried that same detail, the CLI printed it twice (once as the
flattened message, once via reportError's own per-field breakdown).

The redundancy was a symptom of putting a presentation-layer concern
(a fully flattened, human-readable string) into a data field. Reverted
wrapError()'s message construction to short, static, per-stage labels
("Error creating application", etc.) with no appended detail -- this
also means the original [object Object] bug can no longer occur by
construction, since the message no longer attempts to coerce the
rejection into a string at all. The real detail now flows through
rawError alone, and reportError()'s existing (unchanged) formatting
handles it correctly for both single- and multi-error cases, with no
new branching logic needed anywhere.

describeError() is now unused in production code (confirmed via
repo-wide search) -- removed it from utils.ts along with its tests.
Updated the one test that asserted on .error's flattened detail to
instead assert structurally on rawError.exception, which is more
robust and doesn't couple the test to any particular string-formatting
choice.

Verified against the real compiled CLI with both a single-field-error
and a multi-field-error mocked response: single case now prints
exactly one line of detail (previously two identical lines); multi
case correctly prints each field error on its own line, matching the
original pre-regression behavior.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Unknown primitive errors can still crash reportError, and the integration timeout documentation is stale.

0 open findings

Previously missed (2)

In code that hasn't changed since last review

Medium severity Guard message property check for primitive thrown values

src/​utils.ts:94

This fallback still throws before reaching inspect when the thrown value is a number, bigint, or symbol: the preceding 'message' in error check requires an object RHS. Guard that check by type so the newly documented unknown-value handling actually works for these values.

Low severity Update integration test timeout documentation to 240000ms

__tests__/​integration/​setup.js:22

The timeout was doubled here, but __tests__/integration/README.md:115-117 still tells contributors that the default is 120000ms. Update that troubleshooting guidance to 240000ms so it matches the runner.

🧠 Review effort: Balanced

@brob brob left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants