Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions src/commands/explore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,21 @@ function appendFlagHints(
return parts.length > 0 ? `${base} ${parts.join(" ")}` : base;
}

/**
* Coerce the parser's `--field`/`-F` value into an array.
*
* Stricli's variadic parser yields a `string` for a single `-F` flag and a
* `string[]` for multiple, even though the flag is declared variadic. The
* declared type claims `string[] | undefined`, so callers must normalize the
* runtime value before using array methods on it (CLI-28C).
*/
function normalizeFields(field: string[] | undefined): string[] {
if (field === undefined) {
return [];
}
return Array.isArray(field) ? field : [field];
}

/**
* Detect the first aggregate function in the field list.
* Aggregates contain parentheses, e.g., `count()`, `p50(transaction.duration)`.
Expand Down Expand Up @@ -710,11 +725,15 @@ export const exploreCommand = buildListCommand("explore", {
);

let dataset = flags.dataset;
const userSuppliedFields = flags.field && flags.field.length > 0;
let fieldList = [...defaultFieldsForDataset(dataset)];
if (userSuppliedFields) {
fieldList = flags.field;
}
// A single `-F` flag arrives from the parser as a bare string rather than a
// one-element array. Normalize once so every downstream consumer (fieldList,
// hintFlags, contextKey) sees an array — a leftover string makes the later
// `.filter`/`.join` calls throw a TypeError (CLI-28C).
const fields = normalizeFields(flags.field);
Comment thread
sentry[bot] marked this conversation as resolved.
Outdated
const userSuppliedFields = fields.length > 0;
let fieldList = userSuppliedFields
? [...fields]
: [...defaultFieldsForDataset(dataset)];
const timeRange = flags.period;
const environment = parseReplayEnvironmentFilter(flags.environment);

Expand Down Expand Up @@ -806,7 +825,7 @@ export const exploreCommand = buildListCommand("explore", {
const hasMore = !!nextCursor;

const baseTarget = project ? `${org}/${project}` : `${org}/`;
const hintFlags = { ...flags, dataset };
const hintFlags = { ...flags, dataset, field: fields };
const nav = paginationHint({
hasPrev,
hasMore,
Expand Down
22 changes: 22 additions & 0 deletions test/commands/explore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,28 @@ describe("sentry explore", () => {
);
});

test("coerces a single -F flag (string) into an array without crashing", async () => {
// Stricli's variadic parser emits a bare string for a single `-F`, not a
// one-element array. The command must normalize it before the query and
// the pagination-hint path both use array methods on it (CLI-28C).
resolveTargetSpy.mockResolvedValue({ org: "test-org" });
const { context } = createContext();

await func.call(
context,
{
...DEFAULT_FLAGS,
field: "transaction" as unknown as string[],
},
"test-org/"
);

expect(queryEventsSpy).toHaveBeenCalledWith(
"test-org",
expect.objectContaining({ fields: ["transaction"] })
);
});

test("passes custom dataset", async () => {
resolveTargetSpy.mockResolvedValue({ org: "test-org" });
const { context } = createContext();
Expand Down
Loading