Skip to content

fix(): Fix Undefined Crash - #102

Open
Arielpetit wants to merge 1 commit into
Younesfdj:masterfrom
Arielpetit:fix/founder-overall-undefined-guard
Open

fix(): Fix Undefined Crash#102
Arielpetit wants to merge 1 commit into
Younesfdj:masterfrom
Arielpetit:fix/founder-overall-undefined-guard

Conversation

@Arielpetit

Copy link
Copy Markdown

PR: Fix FOUNDER_OVERALL Undefined Crash

Issue

The card builder uses two separate lookup tables for founders:

  • FOUNDERS — visual metadata (art, accent, label)
  • FOUNDER_OVERALL — forced overall rating

The existing implementation checked FOUNDERS to determine whether a user was a founder, but then unconditionally read from FOUNDER_OVERALL:

const founder = FOUNDERS[s.login.toLowerCase()];

const overall = founder
  ? FOUNDER_OVERALL[s.login.toLowerCase()]
  : clamp(baseOVR + Math.round(K.legacy.bonusMax * L), 1, 99);

This assumes the two tables always remain in sync, but there was no protection against them diverging.

If a login exists in FOUNDERS but is missing from FOUNDER_OVERALL:

  • The FOUNDERS lookup succeeds.
  • FOUNDER_OVERALL[...] returns undefined.
  • overall becomes undefined.
  • The card renderer can fail downstream (for example, pad2(undefined) producing "undefined" or arithmetic resulting in NaN).

Additionally, founder overalls bypassed the clamp(1, 99) safety check that every other card receives, allowing invalid values such as 0 or 100 to render unchanged.


Fix

Replaced the single ternary with a guarded two-step lookup:

const founder = FOUNDERS[s.login.toLowerCase()];

const founderOverall = founder
  ? FOUNDER_OVERALL[s.login.toLowerCase()]
  : undefined;

const overall =
  founderOverall !== undefined
    ? clamp(founderOverall, 1, 99)
    : clamp(baseOVR + Math.round(K.legacy.bonusMax * L), 1, 99);

This change provides two safeguards:

  1. If a founder login is missing from FOUNDER_OVERALL, the code now falls back to the normal scoring calculation instead of producing overall = undefined.
  2. Founder overalls are now clamped to the valid range of 1–99, preventing invalid ratings caused by configuration mistakes.

Behavior Before vs. After

Scenario Before After
Founder exists in both tables Forced overall applied correctly No change
Founder exists in FOUNDERS but missing from FOUNDER_OVERALL overall = undefined → render crash Falls back to normal scoring
Founder overall mistakenly set to 0 or 100 Invalid value rendered as-is Value clamped to 1–99
Non-founder Normal scoring No change

Files Changed

File Changes
lib/scoring/engine.ts Replaced the direct FOUNDER_OVERALL lookup with a guarded lookup, added an explicit fallback to normal scoring, and clamped founder overalls to the 1–99 range.
tests/engine.test.ts Added two tests: one verifies scoring falls back correctly when a founder is missing from FOUNDER_OVERALL, and another verifies founder overalls are always clamped to the valid range.

Verification

  • npm test278 passed, 0 failures (22 test files)
  • npm run lint0 errors
  • npm run build → Compiled successfully with no TypeScript errors

@Arielpetit

Copy link
Copy Markdown
Author

@Younesfdj @Mawsis Can you please review this ?

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.

1 participant