Skip to content

feat(kernel): classify telemetry errors by kernel status code#420

Open
mani-mathur-arch wants to merge 3 commits into
mainfrom
mani/kernel-error-telemetry-category
Open

feat(kernel): classify telemetry errors by kernel status code#420
mani-mathur-arch wants to merge 3 commits into
mainfrom
mani/kernel-error-telemetry-category

Conversation

@mani-mathur-arch

@mani-mathur-arch mani-mathur-arch commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

What

The kernel backend returns a structured KernelError carrying an authoritative status Code, but telemetry's classifyError was re-deriving the error category by substring-matching the error message. This adds (*KernelError).Category(), which maps the kernel status code to a telemetry ErrorCategory; classifyError reads it via CategoryFromError (added in #415) and only falls back to message matching for non-kernel errors. cgo.go pins the new status constants to the C enum at compile time.

This mirrors how the other kernel-backed drivers derive the error identity from the kernel code — Python's _CODE_TO_EXCEPTION and Node's mapKernelErrorToJsError. Every kernel status code is mapped (including Internal → generic and InvalidStatementHandlestatement_closed, the same generic buckets Python/Node use), so a *KernelError never depends on the message-substring fallback.

Telemetry-only: the error a caller's Exec/Query returns (full message, sqlstate, queryId via ExecutionError) is unchanged.

Testing

  • TestKernelErrorCategory (all 13 kernel codes + a value outside the enum → "") and TestKernelErrorCategoryThroughWrap (category survives %w wrapping) — pure Go, run under CGO_ENABLED=0.
  • kernel_error_telemetry_e2e_test.go (tagged cgo && databricks_kernel): captures the outbound /telemetry-ext payload on a live warehouse and asserts a real SqlError lands as execute_statement_failed.
  • Verified live against a staging warehouse end to end: SqlError → execute_statement_failed and Cancelled → cancelled observed both on the wire and in the backing frontend_log_sql_driver_log table.

Follow-up (not in this PR)

This PR makes the mapping total over kernel status codes, so any *KernelError is code-classified. Errors that originate in the Go binding itself and carry no kernel code — Arrow schema/batch import failures and result-scan failures — can still reach the message fallback. Attaching a source-declared category at those sites is deferred, because most of them flow through the shared internal/rows/arrowbased layer that #417 / #419 (PECOBLR-3537, Thrift side) are already categorizing; doing it here would overlap those PRs and their new arrowbased/errors.go. Once they land, the residual is a small kernel-binding-only set (the cgo-boundary import failures + a couple of operation.go guards), which can be tagged in a focused follow-up with no conflict.

This pull request and its description were written by Isaac.

Map the kernel's structured status code to a telemetry ErrorCategory via
(*KernelError).Category(), read by classifyError through CategoryFromError,
so a kernel failure reports its authoritative code-derived category instead
of one guessed from the message text. Mirrors the Python driver's
_CODE_TO_EXCEPTION and Node's mapKernelErrorToJsError. Unmapped codes fall
back to message matching. cgo.go pins the new status constants to the C enum.

Co-authored-by: Isaac
Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
Map Internal and InvalidStatementHandle so every kernel status code has a
telemetry category (generic and statement_closed respectively, matching how
Python/Node bucket them). A *KernelError now never falls through to the
message-substring classifier. cgo.go pins the two new constants to the C enum.

Co-authored-by: Isaac
Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
Add TestKernelErrorCategoryExhaustive: every kernel status code must map to a
non-empty category and the map size must match the code list, so a future code
added without a mapping fails CI instead of silently falling back to message
matching (mutation-verified). Correct the codeToCategory doc — only Internal
goes to the generic bucket; InvalidStatementHandle maps to statement_closed.

Co-authored-by: Isaac
Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>

@msrathore-db msrathore-db 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

@mani-mathur-arch mani-mathur-arch added the integration-test-kernel Preview the full passthrough kernel integration suite (live warehouse) label Jul 23, 2026
@github-actions

Copy link
Copy Markdown

Go integration tests triggered (sea / passthrough). View workflow runs.

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

Labels

integration-test-kernel Preview the full passthrough kernel integration suite (live warehouse)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants