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
neverthrow provides a Promise-like entity, with added APIs (e.g. .andThen(), .orElse() which break the way dd-trace identifies promises, and make some code not traceable/wrappable.
From neverthrow's readme:
Encode failure into your program.
This package contains a Result type that represents either success (Ok) or failure (Err).
For asynchronous tasks, neverthrow offers a ResultAsync class which wraps a Promise<Result<T, E>> and gives you the same level of expressivity and control as a regular Result<T, E>.
ResultAsync is thenable meaning it behaves exactly like a native Promise ... except you have access to the same methods that Result provides without having to await or .then the promise! Check out the wiki for examples and best practices.
Sample code to repro the issue (save to test.mjs):
import{err,ok,ResultAsync}from'neverthrow'importtracerfrom'dd-trace'tracer.init()functionbar(){returntracer.trace('bar',()=>{returnResultAsync.fromPromise(Promise.resolve(1))});}functionfoo(){bar().andThen(()=>{console.log('foo.andthen');})}foo();// throws with TypeError: bar(...).andThen is not a function
That's because dd-trace uses this code in tracer._tracer.trace does this here:
So if result is a neverthrow Result object, it is identified as a promise (since it does contains a .then() method), and wrapped, breaking code that relies on it to remain a Result instance.
A "simple" fix could be to account for neverthrow Result specifically, perhaps like this:
if(result&&typeofresult.andThen==='function'){// Intercepting ResultAsync chains from NeverThrowreturnresult.map(value=>{span.finish()returnvalue}).mapErr(error=>{addError(span,error)span.finish()returnerror});}elseif(result&&typeofresult.then==='function'){// Intercepting "standard" Promise chainsreturnresult.then(value=>{span.finish()returnvalue},err=>{addError(span,err)span.finish()throwerr})}else{span.finish()}
The text was updated successfully, but these errors were encountered:
neverthrow provides a Promise-like entity, with added APIs (e.g.
.andThen()
,.orElse()
which break the way dd-trace identifies promises, and make some code not traceable/wrappable.From neverthrow's readme:
Sample code to repro the issue (save to
test.mjs
):That's because dd-trace uses this code in
tracer._tracer.trace
does this here:So if
result
is a neverthrow Result object, it is identified as a promise (since it does contains a.then()
method), and wrapped, breaking code that relies on it to remain a Result instance.A "simple" fix could be to account for neverthrow Result specifically, perhaps like this:
The text was updated successfully, but these errors were encountered: