Skip to content

Commit 8279838

Browse files
committed
refactor(trace-id): extract shared validation, add unit tests (#329)
- Create src/lib/trace-id.ts with shared TRACE_ID_RE and validateTraceId() - Update trace/logs.ts and log/list.ts to use shared module - Remove duplicated regex, validation function, and ValidationError import - Add test/lib/trace-id.test.ts with property-based and unit tests (20 tests) - Add test/commands/log/list.test.ts covering standard and trace modes (20 tests) - Generic error message (no command-specific example) in shared validator
1 parent f5f5ae3 commit 8279838

File tree

6 files changed

+696
-82
lines changed

6 files changed

+696
-82
lines changed

AGENTS.md

Lines changed: 37 additions & 40 deletions
Large diffs are not rendered by default.

src/commands/log/list.ts

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,7 @@ import * as Sentry from "@sentry/bun";
1111
import type { SentryContext } from "../../context.js";
1212
import { listLogs, listTraceLogs } from "../../lib/api-client.js";
1313
import { validateLimit } from "../../lib/arg-parsing.js";
14-
import {
15-
AuthError,
16-
ContextError,
17-
stringifyUnknown,
18-
ValidationError,
19-
} from "../../lib/errors.js";
14+
import { AuthError, ContextError, stringifyUnknown } from "../../lib/errors.js";
2015
import {
2116
buildLogRowCells,
2217
createLogStreamingTable,
@@ -36,6 +31,7 @@ import {
3631
resolveOrg,
3732
resolveOrgProjectFromArg,
3833
} from "../../lib/resolve-target.js";
34+
import { validateTraceId } from "../../lib/trace-id.js";
3935
import { getUpdateNotification } from "../../lib/version-check.js";
4036
import type { Writer } from "../../types/index.js";
4137

@@ -62,24 +58,6 @@ const DEFAULT_POLL_INTERVAL = 2;
6258
/** Command name used in resolver error messages */
6359
const COMMAND_NAME = "log list";
6460

65-
/** Regex for a valid 32-character hexadecimal trace ID */
66-
const TRACE_ID_RE = /^[0-9a-f]{32}$/i;
67-
68-
/**
69-
* Validate that a string looks like a 32-character hex trace ID.
70-
*
71-
* @throws {ValidationError} If the trace ID format is invalid
72-
*/
73-
function validateTraceId(traceId: string): string {
74-
if (!TRACE_ID_RE.test(traceId)) {
75-
throw new ValidationError(
76-
`Invalid trace ID "${traceId}". Expected a 32-character hexadecimal string.\n\n` +
77-
"Example: sentry log list --trace abc123def456abc123def456abc123de"
78-
);
79-
}
80-
return traceId;
81-
}
82-
8361
/**
8462
* Parse --limit flag, delegating range validation to shared utility.
8563
*/

src/commands/trace/logs.ts

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ import { listTraceLogs } from "../../lib/api-client.js";
99
import { validateLimit } from "../../lib/arg-parsing.js";
1010
import { openInBrowser } from "../../lib/browser.js";
1111
import { buildCommand } from "../../lib/command.js";
12-
import { ContextError, ValidationError } from "../../lib/errors.js";
12+
import { ContextError } from "../../lib/errors.js";
1313
import {
1414
formatLogTable,
1515
writeFooter,
1616
writeJson,
1717
} from "../../lib/formatters/index.js";
1818
import { resolveOrg } from "../../lib/resolve-target.js";
1919
import { buildTraceUrl } from "../../lib/sentry-urls.js";
20+
import { validateTraceId } from "../../lib/trace-id.js";
2021

2122
type LogsFlags = {
2223
readonly json: boolean;
@@ -45,30 +46,13 @@ const DEFAULT_PERIOD = "14d";
4546
/** Usage hint shown in error messages */
4647
const USAGE_HINT = "sentry trace logs [<org>] <trace-id>";
4748

48-
/** Regex for a valid 32-character hexadecimal trace ID */
49-
const TRACE_ID_RE = /^[0-9a-f]{32}$/i;
50-
5149
/**
5250
* Parse --limit flag, delegating range validation to shared utility.
5351
*/
5452
function parseLimit(value: string): number {
5553
return validateLimit(value, MIN_LIMIT, MAX_LIMIT);
5654
}
5755

58-
/**
59-
* Validate that a string looks like a 32-character hex trace ID.
60-
*
61-
* @throws {ValidationError} If the trace ID format is invalid
62-
*/
63-
function validateTraceId(traceId: string): void {
64-
if (!TRACE_ID_RE.test(traceId)) {
65-
throw new ValidationError(
66-
`Invalid trace ID "${traceId}". Expected a 32-character hexadecimal string.\n\n` +
67-
"Example: sentry trace logs abc123def456abc123def456abc123de"
68-
);
69-
}
70-
}
71-
7256
/**
7357
* Parse positional arguments for trace logs.
7458
*

src/lib/trace-id.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Shared Trace ID Validation
3+
*
4+
* Provides trace ID regex and validation used by both `trace logs` and
5+
* `log list --trace` commands.
6+
*/
7+
8+
import { ValidationError } from "./errors.js";
9+
10+
/** Regex for a valid 32-character hexadecimal trace ID */
11+
export const TRACE_ID_RE = /^[0-9a-f]{32}$/i;
12+
13+
/**
14+
* Validate that a string looks like a 32-character hex trace ID.
15+
*
16+
* Returns the validated trace ID so it can be used as a Stricli `parse`
17+
* function directly.
18+
*
19+
* @param traceId - The trace ID string to validate
20+
* @returns The validated trace ID (unchanged)
21+
* @throws {ValidationError} If the trace ID format is invalid
22+
*/
23+
export function validateTraceId(traceId: string): string {
24+
if (!TRACE_ID_RE.test(traceId)) {
25+
throw new ValidationError(
26+
`Invalid trace ID "${traceId}". Expected a 32-character hexadecimal string.\n\n` +
27+
"Example: abc123def456abc123def456abc123de"
28+
);
29+
}
30+
return traceId;
31+
}

0 commit comments

Comments
 (0)