You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix secondary stack overflow in wrapUnblock - When _recordBlockingTime() threw an error with a very deep stack trace (e.g. from mutual-recursion across wrapper layers), console.error(error) triggered source-map-support's prepareStackTrace which re-overflowed, causing a secondary RangeError. All console.error calls in DDPQueueCollector now use String(error) to serialize the error message without triggering stack trace reprocessing. See #12.
Move originalUnblock() call into finally block - The cleanup logic (delete self.currentProcessing[session.id] and originalUnblock()) was previously in the try block after the metrics recording. If console.error itself failed in the catch block, these cleanup steps were skipped, permanently stalling the DDP queue for that session. Both are now in a finally block to guarantee execution regardless of error handling failures.
New test: deep-stack error handling - Added unit test verifying that wrapUnblock correctly invokes the original unblock function even when the metrics callback throws an error with a deeply nested stack trace.
Fix root cause: async originalUnblock() via queueMicrotask - The primary stack overflow (#7) was caused by originalUnblock() being called synchronously in the finally block. When another APM agent (e.g. montiapm:agent) also wraps the DDP session's unblock function, the synchronous call chain creates infinite recursion. originalUnblock() is now called via queueMicrotask() to break the synchronous chain. This is safe because Meteor's own runHandlers() independently calls its native unblock after the protocol handler returns — our call is purely for instrumentation.
Conflicting APM agent detection - On startup, DDPQueueCollector now checks for montiapm:agent and mdg:meteor-apm-agent and logs a warning if detected. Running multiple APM agents that wrap DDP internals simultaneously is not recommended.
New test: synchronous recursion prevention - Added cross-collector test simulating 200 chained unblock calls from another APM agent, verifying that queueMicrotask breaks the recursion without stack overflow.