Skip to content

fix(text): pass error (not texture) to SDF font 'failed' handler#53

Merged
chiefcll merged 1 commit into
mainfrom
fix/sdf-font-failed-event-arg
Jun 4, 2026
Merged

fix(text): pass error (not texture) to SDF font 'failed' handler#53
chiefcll merged 1 commit into
mainfrom
fix/sdf-font-failed-event-arg

Conversation

@chiefcll
Copy link
Copy Markdown
Contributor

@chiefcll chiefcll commented Jun 4, 2026

Problem

EventEmitter invokes listeners as (target, data) — every listener's first argument is the emitting object, and the payload is the second argument (EventEmitter.emit calls listener(this, data)).

Texture.setState('failed') emits the error as that second argument (this.emit('failed', this._error)), and the canonical handler type is TextureFailedEventHandler = (target: any, error: TextureError) => void.

The SDF font loader's failed handler instead read it as a single parameter:

atlasTexture.on('failed', (error: Error) => {
  ...
  console.error(`Failed to load SDF font: ${fontFamily}`, error);
  reject(error);
});

So at runtime error was the Texture instance, not the error. The font-load promise still rejected (control flow was fine), but it rejected with — and logged — the texture object instead of the actual TextureError, hurting diagnostics for SDF font load failures.

TypeScript didn't catch it because on()'s listener signature is (target: any, data: any), so the bogus (error: Error) annotation was silently accepted.

Every other texture-event listener in the codebase already uses the correct shape (CoreNode.onTextureFailed = (_, error) =>, SubTexture.onParentTxFailed = (target, error) =>); this was the lone exception.

Fix

  • Handler now reads (_target, error: TextureError).
  • Corrected the type annotation (Error → the real TextureError).
  • Added a regression test that drives loadFont to the failed branch and asserts it rejects with the emitted error (and logs it), not the emitting texture. Verified the test fails on the old code and passes on the fix.

Scope

One-line behavioral fix + test. No API changes. Independent of any other in-flight work.

🤖 Generated with Claude Code

EventEmitter invokes listeners as (target, data), so the error payload
from a Texture's 'failed' event is the second argument. The SDF font
loader's handler read it as a single parameter, so it rejected the
font-load promise and logged with the Texture instance instead of the
actual TextureError.

The font still failed correctly, but the rejection value and console
output were the wrong object, hurting diagnostics for SDF font load
failures. The bogus `(error: Error)` annotation also masked it, since
`on()`'s listener type is `(target: any, data: any)`.

Fix the handler to `(_target, error: TextureError)` and add a regression
test that drives loadFont to the failed branch and asserts it rejects
with the emitted error rather than the emitting texture.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chiefcll chiefcll merged commit 24f349f into main Jun 4, 2026
1 check passed
@chiefcll chiefcll deleted the fix/sdf-font-failed-event-arg branch June 4, 2026 17:12
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