Skip to content

product-sdk-terminal: adapter.destroy() logs benign teardown noise (DestroyedError) to console.error #239

Description

@ReinhardHatko

Summary

@parity/product-sdk-terminal's adapter.destroy() (from createTerminalAdapter) tears down the People-chain statement-store client while in-flight statement subscriptions are still finalizing. polkadot-api's raw client then logs DestroyedError: Client destroyed (prefixed Statement subscription error:) to console.error — often after destroy()'s promise has already resolved, from a detached finalizer.

Login/commands succeed; the line is pure noise. But because it's written unconditionally to console.error, every consumer must hand-roll a benign-teardown filter to keep clean CLI/CI output.

Observed (terminal 0.5.4, a Node CLI)

✓ Signed in.
Statement subscription error: DestroyedError: Client destroyed
    at Object.disconnect [as destroy] (.../@polkadot-api/raw-client/dist/createClient.js:50:28)
    at Object.destroy (.../polkadot-api/dist/src/client.js:237:14)
    at Object.disconnect (.../@novasamatech/statement-store/dist/adapter/lazyClient.js:33:32)
    at teardown (.../@parity/product-sdk-terminal/dist/index.js:82:16)

Note

The 0.5.4 TerminalAdapter.destroy() doc says it "tracks the server-side statement_unsubscribe… RPCs sessions.dispose() fires, then awaits them via Promise.allSettled before destroying the substrate-client request queue." In practice at least one subscription finalizer still escapes that and logs after teardown.

Every consumer works around it

  • bulletin-deploy: isBenignTeardownError (/DestroyedError|Client destroyed/) + a teardown-gated console.error guard.
  • playground-cli: a teardown noise filter in its login command.
  • d3pot: a teardown-gated console.error filter in its session destroy().

Proposed fix

Have adapter.destroy() swallow (or fully await) its own in-flight statement-subscription teardown errors instead of logging them to console.error — same class as surfacing allowance failures via rejections rather than console.error (cf. #168). That removes the duplicated filter from every consumer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions