Skip to content

Remove additional panics in request path - #625

Merged
irees merged 3 commits into
mainfrom
fix-panics
May 23, 2026
Merged

Remove additional panics in request path#625
irees merged 3 commits into
mainfrom
fix-panics

Conversation

@irees

@irees irees commented May 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Converts four production-observed panic(err) sites in request paths to structured error returns so a bad row, malformed enum input, or checker outage no longer takes down the request. Closes interline-io/tlv2#337.

Dataloader batch

  • paramGroupQuery in server/gql/loaders.go no longer panics when the inner query function returns an error. The error is spread across every input index in the failing param group via the existing errs[] slice; dataloader consumers surface it as a per-key error.

WithPerms / AddPerms

  • model.WithPerms returns (context.Context, error) instead of panicking when the Checker can't resolve the caller's permissions. The returned context is the original ctx on error, with no merged PermFilter applied.
  • The AddPerms HTTP middleware logs and writes a JSON 500 via internal/util.WriteJsonError on Checker failure and does not call the downstream handler. Previously this path panicked.
  • checkActive's nil-Checker panic is preserved (it's a config-time misconfiguration, not a runtime error).

Mutations

  • scanCol in server/finders/dbfinder/mutations.go takes a non-nil *error accumulator instead of panicking on Scan failure. Once *errp is set, subsequent scanCol calls short-circuit, so callers chain several and inspect a single error at the end.
  • scanCol skips its internal append when colname is empty, so the existing sites that pre-append the column name explicitly (parent_station, level_id, from_stop_id, to_stop_id) keep working — they pass "" to get only the Scan side effect.
  • The four mutation callbacks (Stop, StopExternalReference, Pathway, Level) declare var err error and propagate it.

Trips

  • tripSelect in server/finders/dbfinder/trip.go returns (sq.SelectBuilder, error) instead of panicking on a RelativeDate enum-parse failure. The three callers (FindTrips, TripsByRouteIDs, TripsByFeedVersionIDs) propagate the error.

Tests

  • New TestAddPerms_CheckerErrorReturns500 and TestAddPerms_SuccessForwardsToDownstream in server/model/perm_filter_test.go lock in the middleware's fail-closed 500 behavior and the happy-path context propagation (stdlib httptest, no DB).
  • Existing WithPerms test sites updated to consume the new (ctx, error) return.

Behavior changes to be aware of

  • Checker resolution failures now return HTTP 500 to the client instead of crashing the process (or relying on panic recovery, depending on framework). Callers that never received error responses for these conditions will start seeing them.
  • Malformed RelativeDate enum values now return a structured GraphQL error instead of crashing the request.
  • Dataloader batch failures now propagate as per-key errors instead of crashing the entire request.
  • scanCol Scan failures now surface as wrapped errors (scan <col>: <inner>) on the mutation response instead of crashing.

Test plan

  • go test ./server/...
  • Send a mutation with a malformed RelativeDate enum and confirm a structured GraphQL error is returned rather than a 500 / crash.
  • Stub the Checker to return an error and confirm /query returns a 500 JSON body and the request log shows the AddPerms: failed to resolve caller permissions error.

@irees
irees marked this pull request as ready for review May 23, 2026 01:01
Copilot AI review requested due to automatic review settings May 23, 2026 01:01

Copilot AI 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.

Pull request overview

This PR removes several production-observed panic(err) sites from request paths and replaces them with structured error propagation so malformed inputs, bad rows, or Checker outages don’t crash requests.

Changes:

  • Convert model.WithPerms to return (context.Context, error) and make AddPerms return a JSON 500 on Checker failure instead of panicking.
  • Propagate dataloader batch errors via per-key errs[] entries rather than panicking.
  • Convert mutation scanCol and trip query construction (tripSelect) to return errors instead of panicking.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
server/model/perm_filter.go Switch WithPerms to error-returning API; AddPerms now fails closed with JSON 500 response.
server/model/perm_filter_test.go Update WithPerms call sites and add tests for AddPerms failure/success behavior.
server/gql/loaders.go Replace panic on batch query failure with per-index error propagation.
server/finders/dbfinder/trip.go Make tripSelect return (builder, error) and return structured error on invalid RelativeDate.
server/finders/dbfinder/mutations.go Replace panic in scan paths with an error accumulator pattern via scanCol(..., errp *error).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/finders/dbfinder/mutations.go
Comment thread server/finders/dbfinder/mutations.go
Comment thread server/finders/dbfinder/mutations.go
Comment thread server/finders/dbfinder/mutations.go
Comment thread server/finders/dbfinder/mutations.go
Comment thread server/finders/dbfinder/mutations.go Outdated
Comment thread server/model/perm_filter.go Outdated
@irees
irees merged commit bc54b2f into main May 23, 2026
6 checks passed
@irees
irees deleted the fix-panics branch May 23, 2026 09:39
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.

2 participants