Skip to content

v2.17.1

Choose a tag to compare

@mariuz mariuz released this 22 Sep 09:52
· 31 commits to master since this release

Patch release addressing post-attachment auxiliary event connection failures, lifecycle management, error reporting, and type definitions for Firebird POST_EVENT subscriptions (attachEvent() / attachEventAsync()).

Summary of Changes

Firebird events operate over a secondary TCP connection (EventConnection) distinct from the primary database wire channel. Prior to this release, unexpected socket disconnections, wire resets, or malformed event packets occurring after successful connection establishment could leave the event manager in an ambiguous state or cause unhandled exceptions. Version 2.17.1 introduces comprehensive error reporting, state transitions, callback guards, and typed event manager interfaces.


Key Improvements

1. Post-Attachment Failure Reporting

  • Event Manager error Event: Unexpected socket errors, remote peer disconnects, unexpected opcodes, or malformed packet payloads occurring after attachment are reported directly through the event manager's error event:
    db.attachEvent(function (err, evtmgr) {
      if (err) throw err;
    
      // Handle unexpected auxiliary connection failures:
      evtmgr.on('error', function (err) {
        console.error('Auxiliary event connection failed:', err);
        // Manager is now CLOSED; re-attach if desired.
      });
    
      evtmgr.registerEvent(['MY_EVENT'], function (err) {
        if (err) throw err;
      });
    });
  • Guarded Fallback: When no 'error' listener is installed on FbEventManager, the driver forwards the error through the database connection's guarded error handler (_emitError), preventing uncaught EventEmitter error crashes.
  • Primary Database Isolation: An auxiliary socket failure marks only the event manager as CLOSED; the primary database connection remains open and functional for queries and transactions.

2. Attachment Callback Idempotency

  • Fixed edge cases where pre-readiness failures could invoke the attachEvent callback multiple times or leave async promises unresolved. The callback and attachEventAsync() promise now resolve or reject strictly once.

3. Graceful Teardown & Intentional Close Suppression

  • Calling evtmgr.close() explicitly marks the auxiliary connection for intentional teardown (_intentionalClose) and detaches callbacks before closing the socket.
  • Suppresses spurious socket teardown errors (e.g. ECONNRESET during socket shutdown) from erroneously bubbling up to the database as application-level errors during deliberate closure.
  • Prevents stale op_event packets from re-queuing event subscription loops during teardown.

4. Wire Protocol Validation

  • Added payload bounds checking (readUInt8 with length validation against the buffer) to safely catch truncated or malformed event packets and convert them to terminal errors.
  • Unhandled wire opcodes received on the auxiliary socket trigger a terminal error cleanly instead of halting event loop execution.

5. TypeScript Definitions

  • Exported complete type interfaces in src/types.ts:
    • FbEventManager: typed event emitter interface with registerEvent, unregisterEvent, close, getState, and typed listeners for post_event and error.
    • FbEventState: typed snapshot of event manager state (IDLE | SUBSCRIBED | CLOSED, registered events, event ID, connection open/closed flags).
    • FbEventManagerCallback: callback signature for attachEvent.
  • Updated Database.attachEvent and Database.attachEventAsync method definitions.

Testing & Verification

  • Added comprehensive unit tests in test/unit/event-connection.test.ts covering:
    • Unexpected post-attachment socket errors and single-emission verification
    • Unexpected socket close handling
    • Intentional shutdown error suppression
    • Unknown opcode and malformed payload handling
    • Pre-ready attachment error settlement
    • Fallback error routing when no manager listener is installed
  • All 228 unit tests pass with 0 linting and 0 TypeScript compilation errors.
  • Passed full CI matrix across Node.js 20, 22, 24, and 26 against Firebird 3, 4, 5, and 6-snapshot.

Documentation

  • Updated README.md event connection section with recommended listener patterns, error recovery guidance, and lifecycle descriptions.

Upgrading

Drop-in replacement for 2.17.0 with no breaking changes. Applications using attachEvent() or attachEventAsync() are recommended to add an evtmgr.on('error', ...) handler before calling registerEvent().

Thanks to @Gobbo89 for #436.