-
Notifications
You must be signed in to change notification settings - Fork 128
Description
I assume you are familiar with ?
operator in Rust? I'm wondering what is the best way to achieve something similar with neverthrow's ResultAsync
.
REST APIs often require to execute a chain of requests that depend on each other, i.e., I cannot spawn them independently but need to await a successful result sequentially. In case of an error, I want to translate the error into a different error type. Here's an example:
type ResponseType = {
some: {
nested: {
field: number
}
},
other: {
nested: {
field: number
}
}
}
async function exampleRequest(arg?: number): Promise<ResponseType> {
return Promise.resolve({
some: {nested: {field: 1}},
other: {nested: {field: 2}},
});
}
function wrap<T>(promise: Promise<T>): ResultAsync<T, Error> {
return ResultAsync.fromPromise(promise, (e) => e as Error);
}
async function requestChain(): Promise<Result<number, string>> {
let aResult = await wrap(exampleRequest())
if (aResult.isErr()) {
return err("something went wrong in request A")
}
let a = aResult.value.some.nested.field
let bResult = await wrap(exampleRequest(a))
if (bResult.isErr()) {
return err("something went wrong in request B")
}
let b = bResult.value.other.nested.field
let cResult = await wrap(exampleRequest(b))
if (cResult.isErr()) {
return err("something went wrong in request C")
}
let c = cResult.value.other.nested.field
return ok(a + b + c)
}
It looks like I'm looking for some kind of unwrapOrReturnError
. In Rust such chains simplify a lot when using the ?
operator. Any thoughts what would be a nice solution with neverthrow?
I feel simply using map
doesn't scale so well, because each request would add a level of indentation (in the specific API case I had a chain of 8 requests). Using andThen
seems tricky as well, because the steps have complex interdependencies, e.g. I would need the results of step 3+4 in step 7, but step 1+3 in step 8 or so.