You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(driver-sql): report an un-run MySQL widening ALTER at error, naming the fix (#9665)
* fix(driver-sql): report an un-run MySQL widening ALTER at `error`, naming the fix (#9609)
Boot schema-sync's MySQL widening swallows a failed `ALTER … MODIFY COLUMN` on
purpose — correctness never depended on the widening having run, and a migration
must not take boot down (#9542 adjudicated exactly that and it is unchanged
here). It reported the swallow at `warn`.
AGENTS.md's degradation rule decides the level with one question: after the
degradation, does the system still look normal from the outside while something
it claims is persisted has not landed? Both halves hold — boot completes and
serves traffic, and the rule's `error` limb names this case verbatim, "DDL that
was supposed to run did not". An un-widened `TIMESTAMP` keeps truncating
milliseconds and an un-widened `TIME` keeps ROUNDING fractional seconds, against
a canonical storage form that promises the milliseconds are kept, and nothing
else reports the column as outstanding. Newly reachable, too: before #9542 the
boot ALTER waited MySQL's one-year default and never returned, so this catch
could not fire on a metadata-lock block at all.
Both messages now report at `error` and carry the second thing an `error` owes —
the FIX: identify the metadata-lock holder with `SHOW PROCESSLIST` or
`performance_schema.metadata_locks`, end it, then re-run `os migrate apply` or
restart, the widening being idempotent. Control flow is untouched.
The gate could not see these sites: `check-durability-degradation-log-level.mjs`
scans all of `packages/` and its baseline is empty, but its durability
vocabulary had no entry for the widening's DDL path. `runWideningAlters` is
declared there now — measured to light up exactly these two catches and nothing
else — so the class stays fixed rather than the two sites.
The emission goes through a named `logDurabilityFailure` helper rather than the
file's inline `(this.logger.error ?? this.logger.warn)(…)`: the gate's matcher
cannot see that parenthesized shape and reports it as a silent swallow, and the
spelling it CAN see, `this.logger.error?.(…)`, prints nothing at all against a
sink that has no `error` — worse than the `warn` it replaces. Pinned by a test
against such a sink.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
* test(driver-sql): type the fixture log sinks so `error` stays OPTIONAL (#9609)
The level-recording fixture supplies `error`, so its inferred logger type made
`error` REQUIRED — and the no-error-sink twin, whose entire job is to be a sink
without one, then could not extend it (TS2416/TS2322).
Both fixtures now annotate `FakeLogSink`, which spells `error?` exactly as
`SqlDriver` declares it. That is the contract under test, not a workaround: the
optional `error` is the whole reason `logDurabilityFailure` needs a fallback.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
---------
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments