feat: add send-event and send-envelope commands with DSN auth#921
Merged
Conversation
Contributor
|
Contributor
Codecov Results 📊❌ Patch coverage is 78.52%. Project has 4355 uncovered lines. Files with missing lines (3)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 81.97% 81.97% —%
==========================================
Files 329 334 +5
Lines 24023 24157 +134
Branches 15715 15807 +92
==========================================
+ Hits 19692 19802 +110
- Misses 4331 4355 +24
- Partials 1654 1659 +5Generated by Codecov Action |
BYK
added a commit
that referenced
this pull request
May 5, 2026
- parseTimestamp now throws ValidationError on invalid input instead of silently falling back to Date.now() (Seer/Cursor) - Environ spread order fixed: process.env goes first so user --extra environ:val correctly overrides it (Cursor) - Raw mode no longer reads file twice: decode bytes in-memory instead of re-reading (Cursor) - Fixed --raw help text: sends raw bytes directly, not 'inside an envelope' (Sentry) - send-envelope now errors when no files provided (Sentry) - send-event --raw in inline mode now throws ValidationError (Sentry)
Member
Author
|
Fixed all 6 bot findings in 7e33546:
|
BYK
added a commit
that referenced
this pull request
May 5, 2026
…eation in try/catch - Centralise ENOENT/IO error handling into shared readFileBytes() in transport.ts - Removes duplicated file-reading error block from both send-event.ts and send-envelope.ts - Wrap makeDsn() call in try/catch to guard against future SDK internal throws - Wrap createEventEnvelope()+serializeEnvelope() in try/catch with descriptive ValidationError Addresses Sentry Seer findings (medium) and Cursor Bugbot finding (low) on PR #921.
Implements sentry send-event and sentry send-envelope — the first
commands that authenticate via a DSN (not a Bearer token), matching
the old sentry-cli behaviour.
Architecture:
- src/lib/envelope/transport.ts: shared DSN-based envelope sender
using @sentry/core (makeDsn, getEnvelopeEndpointWithUrlEncodedAuth,
serializeEnvelope) — no new dependencies
- src/lib/envelope/event-builder.ts: builds a Sentry Event from CLI
flags (message, level, tags, extras, user, fingerprint, etc.)
- auth: 'dsn' in buildCommand: skips Bearer token guard and RC URL
check for DSN-only commands
send-event flags (matching old CLI):
--dsn, -m/--message, -l/--level, -r/--release, -E/--env,
-t/--tag (variadic), -e/--extra (variadic), -u/--user (variadic),
-f/--fingerprint (variadic), --dist, --platform, --timestamp,
--no-environ, --raw
send-envelope flags:
--dsn, --raw (send bytes without parsing)
Tests: 48 new tests across 4 files (TDD — tests written first)
- transport: URL construction, auth params, error handling
- event-builder: parseKeyValue, parseUserFields, buildEventFromFlags
- send-event command: inline, file, JSON output, missing DSN
- send-envelope command: valid file, raw mode, invalid envelope,
multiple files, missing DSN
sentry send event -- canonical new interface sentry send envelope sentry send-event -- hidden bw-compat alias (old sentry-cli) sentry send-envelope -- hidden bw-compat alias (old sentry-cli)
- parseTimestamp now throws ValidationError on invalid input instead of silently falling back to Date.now() (Seer/Cursor) - Environ spread order fixed: process.env goes first so user --extra environ:val correctly overrides it (Cursor) - Raw mode no longer reads file twice: decode bytes in-memory instead of re-reading (Cursor) - Fixed --raw help text: sends raw bytes directly, not 'inside an envelope' (Sentry) - send-envelope now errors when no files provided (Sentry) - send-event --raw in inline mode now throws ValidationError (Sentry)
- Remove undocumented DSN auto-detection claim from send-event.ts module comment and requireDsn error message (only --dsn and SENTRY_DSN are actually supported) - Use Number.isFinite instead of !Number.isNaN to reject Infinity and -Infinity as timestamp values
- parseTimestamp: remove && num > 0 guard — epoch-0 and negative timestamps are valid; the old guard silently corrupted them to year 2000 / year 3600 via Date.parse fallthrough - resolveDsn: trim whitespace from --dsn flag and SENTRY_DSN env var (leading space / trailing newline from shell caused confusing error) - transport test: use .toThrow(ValidationError) not bare .toThrow() - send.md: remove false claim that DSN auto-detects from project files - buildFilePayload + send-envelope: wrap Bun.file reads in try/catch, surface ENOENT and parse errors as ValidationError not raw stacks - Document that --message is ignored when file args are provided - Add tests: ENOENT → ValidationError, --raw without file → error, no files for send-envelope → ValidationError, DSN whitespace trim, whitespace trim for SENTRY_DSN env var
…eation in try/catch - Centralise ENOENT/IO error handling into shared readFileBytes() in transport.ts - Removes duplicated file-reading error block from both send-event.ts and send-envelope.ts - Wrap makeDsn() call in try/catch to guard against future SDK internal throws - Wrap createEventEnvelope()+serializeEnvelope() in try/catch with descriptive ValidationError Addresses Sentry Seer findings (medium) and Cursor Bugbot finding (low) on PR #921.
…atch Mirrors the file-based path's error handling — catches any internal SDK errors and re-throws as ValidationError.
Calling buildEnvelopeUrl(dsn) before the file read loop ensures invalid DSNs are caught upfront rather than after unnecessary I/O, consistent with send-event's behavior.
getEnvelopeEndpointWithUrlEncodedAuth appends /<version> internally, so passing 'sentry-cli/dev' produced the malformed identifier sentry_client=sentry-cli/dev/dev on every envelope request. Now passes bare name 'sentry-cli' and lets the SDK append '/dev'.
…r message - makeDsn may throw SentryError internally; wrap in try/catch for safety - requireDsn error message now uses canonical 'sentry send event' instead of hardcoded 'sentry send-event' (wrong for send-envelope callers)
- Canonical command is now 'sentry event send' under the event route - send-envelope is now a deprecation shim suggesting 'sentry event send --raw' - send-event remains as a hidden backward-compat alias - Removed the 'send' route group entirely - Updated docs, tests, and all references
Prevents HostScopeError from masking the deprecation message when a .sentryclirc file is present.
- Replace Bun.file() with node:fs/promises readFile in transport.ts - Replace bun:test imports with vitest in all test files - Replace mock() with vi.fn(), spyOn with vi.spyOn - Convert require() to static imports - Regenerate docs/skill files for post-rebase state
b6ec9ac to
562717a
Compare
Parses a log file into breadcrumbs attached to the event, matching the old sentry-cli send-event --logfile behavior: - Reads file line by line - Optionally parses 'CATEGORY: message' prefixes (--with-categories) - Uses file mtime as breadcrumb timestamp - Caps at 100 breadcrumbs (keeps the last 100 lines) Used by the self-hosted installer's error reporting: sentry-cli send-event --logfile $INSTALL_LOG ... 4 new tests: basic logfile, with-categories parsing, nonexistent file error, 100-breadcrumb cap with correct last-N behavior.
Empty messages like 'ERROR:' now correctly produce {category: 'ERROR', message: ''}
instead of falling through to the default 'log' category.
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9720128. Configure here.
Number(' ') returns 0, silently producing epoch-zero timestamps.
Now trims and checks for empty before numeric parsing.
- Add log.debug() to all 4 silent catch blocks (AGENTS.md compliance) - Replace hardcoded exit code 1 with EXIT.GENERAL in send-envelope shim - Remove unused _cwd parameter from resolveDsn/requireDsn - Add 5 new parseTimestamp tests: Unix epoch int/float, ISO 8601, invalid string → ValidationError, whitespace-only → default
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Implements
sentry event sendfor old sentry-cli parity. Ref #600.This is the first command in the new CLI that authenticates via a DSN (not a Bearer token), so no
sentry auth loginis needed — provide a DSN via--dsnorSENTRY_DSNenv var.Command structure
sentry event sendSend a Sentry event from CLI flags or a JSON file:
Full flag parity with old
sentry-cli send-event:--message,--level,--release,--env,--tag,--extra,--user,--fingerprint,--timestamp,--dist,--platform,--no-environ--logfile,--with-categories(breadcrumbs from log files, used by self-hosted installer)--raw(send file bytes as-is, replacessend-envelope)Design decisions
event sendunder the event group — follows the mutation pattern (project create,issue resolve). Discoverable viasentry event --help.send-envelopedeprecated — envelopes are a low-level concept;--rawcovers the use case. Runningsentry send-envelopethrows with a clear message suggestingsentry event send --raw <file>.auth: "dsn"onbuildCommandskips the token guard and RC URL check. DSN resolved from--dsnflag orSENTRY_DSNenv var.Shared infrastructure
src/lib/envelope/transport.ts—requireDsn(),buildEnvelopeUrl(),sendEnvelopeRequest(),readFileBytes()src/lib/envelope/event-builder.ts—buildEventFromFlags(),parseBreadcrumbsFromLogfile()@sentry/corefor envelope creation/serialization and DSN parsing — no new dependenciesTests
60 tests across 4 files:
transport.test.ts— URL construction, auth params, error handling, DSN whitespace trimevent-builder.test.ts— all flags, parseKeyValue, parseUserFields, parseTimestamp edge cases, logfile breadcrumbs (basic, with-categories, ENOENT, 100-cap)send.test.ts— inline mode, JSON output, tags, missing DSN, ENOENT, --raw without filessend-envelope.test.ts— deprecation shim error message