Skip to content

fix(core): don't console.error the raw query error in handleFallbackJoin - #11206

Open
Didactora wants to merge 1 commit into
better-auth:mainfrom
Didactora:fix/no-bare-console-error-in-fallback-join
Open

fix(core): don't console.error the raw query error in handleFallbackJoin#11206
Didactora wants to merge 1 commit into
better-auth:mainfrom
Didactora:fix/no-bare-console-error-in-fallback-join

Conversation

@Didactora

@Didactora Didactora commented Sep 7, 2026

Copy link
Copy Markdown

What

handleFallbackJoin catches a storage fault, logs it through logger.error, and then calls a bare console.error(error) before rethrowing. This moves the caught error into the logger.error call that is already there and drops the bare console call.

  } catch (error) {
      logger.error(`Failed to query fallback join for model ${modelName}:`, {
          where,
          limit: joinConfig.limit,
+         error,
      });
-     console.error(error);
      throw error;
  }

Why

The error reaching this catch is normally a driver error. For Drizzle, DrizzleQueryError's message is built unconditionally in queryWithCache as:

Failed query: <sql>
params: <params>

handleFallbackJoin is on well-travelled paths — findSession passes join: { user: true }, so it runs on every session read; findOAuthUser runs on the OAuth callback; findUserByEmail with includeAccounts runs on sign-in and password reset. So on a transient database fault, the bare console.error writes query parameters — a user id on the session leg, an email on a user lookup — straight to stderr, bypassing whatever logger the consumer configured.

That matters most on serverless hosts, where stderr is the log store and the lines are retained. A consumer who deliberately installs a logger.log handler to strip identifiers currently has no way to reach this one call site: it is not routed through the logger, and it is inside a closure the adapter option cannot wrap.

Why this shape rather than deleting the line

The diagnostic is worth keeping — it is just going to the wrong place. Passing error as a structured field on the logger.error immediately above it preserves the information for anyone who wants it, routes it through the same logger as every other diagnostic in this file, and lets a consumer who sanitizes their logger actually get sanitization. No information is lost; only the bypass is.

Notes

  • No behaviour change beyond the log destination: the throw error below is untouched, so callers see exactly the same failure.
  • Verified against main (packages/core/src/db/adapter/factory.ts), and the same block is present in the published 1.6.23 and 1.7.3 dists.

Summary by cubic

Routes the fallback join error through the configured logger.error instead of a bare console.error, so driver error messages containing query parameters no longer bypass consumer log sanitization and write to stderr (which is the log store on serverless hosts).

  • The error is passed as a structured field on the existing logger.error call, so no diagnostic information is lost.
  • handleFallbackJoin runs on session reads, OAuth callbacks, and sign-in and password-reset lookups.
  • The throw error below is untouched, so callers see the same failure.

Written for commit bc58820. Summary will update on new commits.

Review in cubic

The caught error is passed to `logger.error` instead of being printed with a
bare `console.error`, so it goes through the configured logger like every other
diagnostic in this file.

Why it matters: the error reaching this catch is usually a driver error, and for
Drizzle a `DrizzleQueryError`'s message is built unconditionally as
`Failed query: <sql>\nparams: <params>`. `handleFallbackJoin` runs on the
session-read path (`findSession` passes `join: { user: true }`), on the OAuth
callback (`findOAuthUser`) and on sign-in/password-reset (`findUserByEmail` with
`includeAccounts`), so on a transient database fault that bare call writes query
parameters straight to stderr - past any `logger` the consumer configured. On a
serverless host stderr is the log store, so those parameters are retained.

The line above it already logs the same failure through `logger`, so nothing is
lost by routing the error the same way: consumers who want the full error still
get it as a structured field, and consumers who sanitize their logger now
actually get sanitization.
@Didactora
Didactora requested a review from a team as a code owner September 7, 2026 19:26
@Didactora
Didactora requested review from Bekacru and removed request for a team September 7, 2026 19:26
@vercel

vercel Bot commented Sep 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
better-auth Skipped Skipped Sep 7, 2026 7:27pm UTC

@vercel

vercel Bot commented Sep 7, 2026

Copy link
Copy Markdown

@Didactora is attempting to deploy a commit to the better-auth Team on Vercel.

A member of the Team first needs to authorize it.

@better-release better-release Bot added the core Core infra, API routes, session, cookies, client SDK label Sep 7, 2026
@greptile-apps

greptile-apps Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Routes fallback-join query errors through the configured logger instead of bypassing it with a direct console call.

  • Adds the caught error to the existing structured log metadata.
  • Preserves the original rethrow behavior.
  • Allows custom logger implementations to sanitize or redirect the diagnostic.

Confidence Score: 5/5

The PR appears safe to merge and preserves both diagnostics and error propagation while respecting configured logging behavior.

The established logger contract supports Error objects in metadata, custom handlers receive the metadata unchanged, and the caught error is still rethrown without altering caller-visible behavior.

Reviews (1): Last reviewed commit: "fix(core): don't console.error the raw q..." | Re-trigger Greptile

@cubic-dev-ai cubic-dev-ai Bot 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.

No issues found across 1 file

Re-trigger cubic

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

Labels

core Core infra, API routes, session, cookies, client SDK

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant