@wix/monitoring-browser-sentry
v0.21.0
Published
A Sentry adapter for monitoring in external apps.
Downloads
8,381
Maintainers
Keywords
Readme
@wix/monitoring-browser-sentry
A Sentry adapter for monitoring in external apps.
[!NOTE] We support a lazy Sentry instance, but from the user perspective all methods in the adapter always run synchronously
Semi-custom implementation of spans
Why is a custom implementation required?
The lazy Sentry instance doesn't include any spans functionality, meaning that we need to implement parts of it while we wait for the full SDK to load.
startSpan()
We execute all code synchronosuly if we received the full SDK upfront and when the full SDK was already loaded.
If the full SDK was not loaded yet, we do the following:
- Start preloading the full SDK
- Run the user callback synchronously (the callback itself can be sync or async, we handle both cases)
- Record the duration of the callback execution
- Catch any unhandled errors thrown from the callback and save the reference to the error
- Rethrow the error so that the user code fails
- Return the return value of the callback
- When the full SDK is ready call
Sentry.startSpan()with a simulated callback:- The callback runs the same amount of time as the original one
- The callback throws the same error as the original one
- We wrap the
Sentry.startSpan()call withtry/catchbecause Sentry will rethrow the error- We will rethrow the error if it is thrown from within
Sentry.startSpan()unexpectedly
- We will rethrow the error if it is thrown from within
- We wrap the
startSpanManual()
A custom implementation of a manual span, which doesn't involve a callback and instead returns a ManualSpan instance that allows to end the span successfully or fail it with a provided Error or error message.
Under the hood we still call Sentry.startSpan() but provide a callback that returns a Promise, which gives us the ability to resolve or reject it on demand, at which Sentry will report it.
- We save the
ManualSpaninstance using the span name in a map- Consecutive calls to
startSpanManual()with the same span name will override the mapped value, it is up to the user to end the span before starting a new one - If the full SDK was not loaded yet we trigger and subscribe to the fullSDK and save a promise of type
ManualSpan
- Consecutive calls to
- We return a
ManualSpaninstance to the user to allow ending or failing the span manually - If the full SDK was not loaded yet we handle the
end()andfail()calls asynchronously (but hide this fact from the user) - When
end()is called we resolve the callback promise (and then Sentry reports the span)- The span is then removed from the map
- When
fail()is called we reject the callback promise (and then Sentry marks the span as failed and reports it)- The span is then removed from the map
- We catch the rejection because Sentry will rethrow the error
- We will rethrow the error if it is thrown from within
Sentry.startSpan()unexpectedly
- We will rethrow the error if it is thrown from within
- We report the span only once even if multiple
end()orfail()calls were made
endSpanManual()
Allows to end a span that was created via startSpanManual() by name, rather than via the returned ManualSpan object.
This methods allows to end only the last span that was created. It is up to the user to make sure there is no ambiguity (i.e. multiple started spans) when they call this method.
- We get the pending
ManualSpaninstance using the span name from our map and then callend()if the span exists- The span is then removed from the map
- We report the span only once even if multiple
endSpanManual()calls were made
A note about isolation of manual spans
- In the browser we report manual spans with the
forceTransaction: trueflag because spans are reported globally and we want to avoid grouping spans under the same transaction, and more importantly avoid grouping if they were reported from different apps - We create the map of the pending manual spans pepr the provided
dsnto avoid conflict between apps that report spans with the same name
