Skip to content

use http.response.status_code for traces status filter#407

Open
heiwen wants to merge 4 commits intomainfrom
claude-issue-406-20260417-1005
Open

use http.response.status_code for traces status filter#407
heiwen wants to merge 4 commits intomainfrom
claude-issue-406-20260417-1005

Conversation

@heiwen
Copy link
Copy Markdown
Contributor

@heiwen heiwen commented Apr 17, 2026

Use http.response.status_code instead of span_status_code for traces status filtering and formatting. Bun returns bigint columns as strings, so formatStatus parses the string to a number before comparison. NULL HTTP status (no response) is treated as error consistently.

Closes #406

Generated with Claude Code

Summary by CodeRabbit

  • Documentation

    • Added guidance on handling database bigint values that are returned as strings, including instructions for parsing these values before performing arithmetic or numeric comparisons.
  • Bug Fixes

    • Updated trace status filtering to use HTTP response status codes for improved accuracy in status classification, with "ok" for successful responses and "error" for failed responses.

Switch from span_status_code to http.response.status_code for determining
trace status. Bun returns bigint columns as strings, so formatStatus parses
the string to a number before comparison. NULL HTTP status (no response)
is treated as error consistently.

Closes #406

Co-authored-by: Heinrich Wendel <heiwen@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 17, 2026

Warning

Rate limit exceeded

@heiwen has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 46 minutes and 12 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 46 minutes and 12 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aecf6321-c9a3-43d4-b909-dc0b891af25d

📥 Commits

Reviewing files that changed from the base of the PR and between 3194e99 and 7215f1c.

📒 Files selected for processing (1)
  • apps/api/src/modules/traces/service.ts
📝 Walkthrough

Walkthrough

The changes update trace status filtering from OTel span status codes to HTTP response status codes, restoring 4xx client error visibility in error filters. Documentation guidelines added clarifying Bun.sql's bigint-to-string behavior.

Changes

Cohort / File(s) Summary
Documentation
AGENTS.md
Added guideline documenting that Bun.sql returns bigint database columns as strings; instructs parsing to numbers before arithmetic or numeric comparisons.
Traces Status Filtering
apps/api/src/modules/traces/service.ts
Replaced span_status_code-based filtering with HTTP response status code logic in listTraces and getSpans; ok now matches HTTP codes < 400, error matches null or codes >= 400. Updated query projections to select span_attributes.http.response.status_code and compute status via updated formatStatus.
Status Formatting Logic
apps/api/src/modules/traces/utils.ts
Updated formatStatus to accept httpStatusCode parameter; replaced string-based OTel status mapping with numeric HTTP classification; converts input to Number, returns "error" for codes >= 400, "ok" otherwise, and "error" as fallback for non-numeric values.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • feat: improved traces filters #286 — Directly related traces filtering changes; both PRs modify apps/api/src/modules/traces/service.ts status handling logic and the formatStatus function.

Suggested reviewers

  • turisanapo

Poem

🐰 A humble bunny hops with glee,
Four-oh-fours are now to see!
HTTP codes dance in the query,
No more status errors left blurry,
String-to-number conversions bright,
Trace filters now shine just right! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and accurately describes the main change: switching to HTTP response status codes for trace status filtering.
Linked Issues check ✅ Passed The PR successfully implements all objectives from issue #406: uses HTTP status code for filtering, updates formatStatus to handle HTTP status values and bigint-as-string conversion, and adds documentation about Bun's bigint handling.
Out of Scope Changes check ✅ Passed All changes are directly aligned with issue #406 objectives: HTTP status filtering implementation in service.ts, formatStatus updates in utils.ts, and Bun bigint documentation in AGENTS.md.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude-issue-406-20260417-1005

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@heiwen
Copy link
Copy Markdown
Contributor Author

heiwen commented Apr 17, 2026

@claude add some knowledge to your AGENTS.md so that you remember that Bun.sql returns bigint numbers as string.

@hebo-agent
Copy link
Copy Markdown

hebo-agent Bot commented Apr 17, 2026

Claude finished @heiwen's task in 35s —— View job


Adding Bun.sql knowledge to AGENTS.md

  • Read current AGENTS.md
  • Add Bun.sql bigint knowledge
  • Commit and push changes

Added a note under Key Technologies & Use Cases in AGENTS.md documenting that Bun.sql returns bigint columns as strings, and that values must be parsed to numbers before numeric comparisons.

Co-authored-by: Heinrich Wendel <heiwen@users.noreply.github.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1740b89b1b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/api/src/modules/traces/service.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/api/src/modules/traces/service.ts (1)

183-213: ⚠️ Potential issue | 🟠 Major

getSpans labels all non-HTTP internal spans as "error" due to missing HTTP status code.

In getSpans (line 246), all spans are assigned status via formatStatus(row.http_status_code). The formatStatus function returns "error" when the HTTP status code is null or undefined. Since internal gen_ai spans (embeddings, tool calls, reasoning steps, etc.) do not carry the http.response.status_code attribute, they will all be labeled as "error" in the span detail view.

While the PR's intent to treat NULL HTTP status as error is reasonable for listTraces (where the root span is HTTP-level), this breaks getSpans where most spans are internal operations without HTTP responses. The current implementation lacks any fallback to actual OpenTelemetry span status.

Either restore span_status_code as the status source for getSpans, or combine both signals: treat a span as "error" only if http_status_code >= 400 OR span_status_code indicates error; otherwise "ok".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/api/src/modules/traces/service.ts` around lines 183 - 213, getSpans
currently uses formatStatus(row.http_status_code) which treats NULL as "error",
mislabeling internal non-HTTP spans; update getSpans to prefer the OpenTelemetry
span status (span_status_code / span_status_message) and only use
http_status_code when present and >= 400. Specifically, include
"span_status_code" in the SELECT (or ensure the existing span_status_code field
is returned) and change the status resolution in getSpans to: if
http_status_code != null then use formatStatus(http_status_code) treating >=400
as error, else fall back to span_status_code (or combine: mark error if
http_status_code >=400 OR span_status_code indicates ERROR); adjust calls to
formatStatus or add a new helper to reflect this combined logic.
🧹 Nitpick comments (3)
apps/api/src/modules/traces/service.ts (1)

88-94: Status filter LGTM; consider an index/verify column cardinality.

Filtering on span_attributes.http.response.status_code alongside the existing time-range + agent/branch/org predicates is correct and matches the new formatStatus semantics. The IS NULL OR >= 400 branch correctly preserves visibility of 4xx and of spans that never produced a response.

One operational note: if traces volume is high, confirm GreptimeDB has this column indexed (or that the time-range + tag filters sufficiently prune before this predicate is evaluated). Otherwise status-filtered queries may scan considerably more than before.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/api/src/modules/traces/service.ts` around lines 88 - 94, The
status-filter logic using HTTP_STATUS_COL (the string constant for
"span_attributes.http.response.status_code") and the statusFilterSql branches is
fine; now verify DB performance by ensuring the column is indexed or
sufficiently selective with existing time-range + agent/branch/org predicates—if
not, add an index (or a composite index including the time/tags) on
span_attributes.http.response.status_code or adjust query plans; also check the
column cardinality and query explain plans for the functions that build
statusFilterSql to confirm the predicate doesn't force large table scans.
apps/api/src/modules/traces/utils.ts (2)

41-41: Parse bigint strings with Number.parseInt/parseFloat for clarity, or handle bigint type explicitly.

Bun.sql may also hand back actual bigint values in some driver paths; Number(bigint) works but typeof check here only branches on string vs falls through. Current behavior is correct for the documented case (string), but consider being explicit:

♻️ Optional explicit handling
-  const code = typeof httpStatusCode === "string" ? Number(httpStatusCode) : httpStatusCode;
+  const code =
+    typeof httpStatusCode === "string" || typeof httpStatusCode === "bigint"
+      ? Number(httpStatusCode)
+      : httpStatusCode;

As per coding guidelines: "Always parse string values from Bun.sql bigint columns to numbers before performing arithmetic or numeric comparisons".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/api/src/modules/traces/utils.ts` at line 41, The current assignment for
the variable named code (const code = typeof httpStatusCode === "string" ?
Number(httpStatusCode) : httpStatusCode) only distinguishes strings and falls
through for other types; update this to explicitly handle string and bigint
types: if httpStatusCode is a string parse it with Number.parseInt or
Number.parseFloat as appropriate, if it is a bigint convert it to a Number (or
handle overflow/edge-cases per project rules), otherwise keep the existing
numeric value—modify the expression that sets code (referencing httpStatusCode
and the const code) to perform these explicit type branches.

40-46: Dead branch in return type: "unknown" is no longer reachable.

formatStatus now returns only "ok" or "error" — the "unknown" arm was removed but is still declared in the return type. Narrow the signature so callers (and the Elysia/Eden schema surface downstream) reflect reality.

♻️ Proposed narrowing
-export function formatStatus(httpStatusCode: unknown): "ok" | "error" | "unknown" {
+export function formatStatus(httpStatusCode: unknown): "ok" | "error" {
   const code = typeof httpStatusCode === "string" ? Number(httpStatusCode) : httpStatusCode;
   if (typeof code === "number" && Number.isFinite(code)) {
     return code >= 400 ? "error" : "ok";
   }
   return "error";
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/api/src/modules/traces/utils.ts` around lines 40 - 46, The declared
return type for formatStatus is inaccurate: update the function signature to
remove the unreachable "unknown" variant and declare the return type as "ok" |
"error" only; keep the implementation (casting httpStatusCode, checking
Number.isFinite and >=400) but change the function's declared return type to
match its actual outputs so downstream schema and callers reflect the narrowed
type (function name: formatStatus).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@apps/api/src/modules/traces/service.ts`:
- Around line 183-213: getSpans currently uses
formatStatus(row.http_status_code) which treats NULL as "error", mislabeling
internal non-HTTP spans; update getSpans to prefer the OpenTelemetry span status
(span_status_code / span_status_message) and only use http_status_code when
present and >= 400. Specifically, include "span_status_code" in the SELECT (or
ensure the existing span_status_code field is returned) and change the status
resolution in getSpans to: if http_status_code != null then use
formatStatus(http_status_code) treating >=400 as error, else fall back to
span_status_code (or combine: mark error if http_status_code >=400 OR
span_status_code indicates ERROR); adjust calls to formatStatus or add a new
helper to reflect this combined logic.

---

Nitpick comments:
In `@apps/api/src/modules/traces/service.ts`:
- Around line 88-94: The status-filter logic using HTTP_STATUS_COL (the string
constant for "span_attributes.http.response.status_code") and the
statusFilterSql branches is fine; now verify DB performance by ensuring the
column is indexed or sufficiently selective with existing time-range +
agent/branch/org predicates—if not, add an index (or a composite index including
the time/tags) on span_attributes.http.response.status_code or adjust query
plans; also check the column cardinality and query explain plans for the
functions that build statusFilterSql to confirm the predicate doesn't force
large table scans.

In `@apps/api/src/modules/traces/utils.ts`:
- Line 41: The current assignment for the variable named code (const code =
typeof httpStatusCode === "string" ? Number(httpStatusCode) : httpStatusCode)
only distinguishes strings and falls through for other types; update this to
explicitly handle string and bigint types: if httpStatusCode is a string parse
it with Number.parseInt or Number.parseFloat as appropriate, if it is a bigint
convert it to a Number (or handle overflow/edge-cases per project rules),
otherwise keep the existing numeric value—modify the expression that sets code
(referencing httpStatusCode and the const code) to perform these explicit type
branches.
- Around line 40-46: The declared return type for formatStatus is inaccurate:
update the function signature to remove the unreachable "unknown" variant and
declare the return type as "ok" | "error" only; keep the implementation (casting
httpStatusCode, checking Number.isFinite and >=400) but change the function's
declared return type to match its actual outputs so downstream schema and
callers reflect the narrowed type (function name: formatStatus).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4665a2a1-5505-402b-8a88-43642661de88

📥 Commits

Reviewing files that changed from the base of the PR and between 176deb9 and 3194e99.

📒 Files selected for processing (3)
  • AGENTS.md
  • apps/api/src/modules/traces/service.ts
  • apps/api/src/modules/traces/utils.ts

@heiwen
Copy link
Copy Markdown
Contributor Author

heiwen commented Apr 17, 2026

Open Issue: if we don't set span_status_code, there is also no error message

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.

Use http.response.status_code in traces status filter to preserve 4xx error visibility

1 participant