• v3.14.0 3c34b2f0cf

    v3.14.0 — log panel shows line context
    All checks were successful
    CI / build-and-test (push) Successful in 2m27s
    Stable

    joeyr released this 2026-08-03 13:38:30 -05:00 | 21 commits to main since this release

    The application log panel was showing you less than the log file it mirrors.
    This release closes that gap.

    What was wrong

    Every log call in this app already attaches structured context — which champion,
    which role, which attempt, which error. forwardStream then parsed each pino
    line and rebuilt it as a fixed four-field record:

    const record: AppLogRecord = {
      at, level, msg, event,   // <- everything else dropped here
    };
    

    So a failed rune fetch wrote championId and role to debug.log, and showed
    the panel Rune options fetch failed and nothing more. The panel was strictly
    worse than the file for the same line — which is backwards, because the panel is
    the log view you can actually reach while a game is running.

    The block now

    18:42:07 WARN  rune_options.fetch_failed Rune options fetch failed  championId=63 role=mid err=Timeout: op.gg did not answer in 8000ms
    18:42:09 ERROR window.renderer_gone      Renderer "companion" exited (crashed)  window=companion reason=crashed exitCode=133
    

    Trailing key=value chips, dimmed so a row still reads message-first. The
    filter box matches them too, so championId=63 narrows to one champion's lines.

    Design

    • An open bag, not named fields. Context arrives as whatever the call site
      attached, minus the four keys the panel renders in their own columns. A new
      field therefore reaches the UI without touching the logger, the IPC contract,
      the store and the component — which is what the old shape charged for it.
    • One line high, always. Scalars print bare; objects and arrays collapse to
      compact JSON. The full record is in debug.log — the panel is for triage, so
      a row that stays scannable beats a row that is complete.
    • err gets its own treatment. Pino's {type, message, stack} renders as
      err=Timeout: op.gg did not answer, with the stack on hover. Inlining a stack
      in a scrolling list would bury the twenty lines around it.

    Errors now keep their stacks

    52 call sites across 26 files logged err instanceof Error ? err.message : String(err) — the stack discarded before it ever reached the log. They pass the
    Error itself now; pino serialises it, so no logger configuration changed.

    Being straight about the value: 44 of those 52 are warns on expected failure
    paths — a fetch that failed, an LCU frame that would not parse — where the
    message is the diagnosis and the stack points into Node internals. This
    matters for the handful of broad catch blocks, where "Cannot read properties
    of undefined" previously named no location at all. It also stops a non-Error
    throw stringifying to [object Object]; pino passes such values through whole.


    Minor rather than patch for the new panel output. No settings, no LCU writes and
    no data-source changes; nothing to reconfigure after updating.

    Downloads