neverthrow
neverthrow copied to clipboard
Early return / short circuit pattern
Hey , any recommendations on how to do the following pattern in a route handler, hopefully the pseudo code makes sense:
(req, res, next) => {
loadUser(req)
.andThen(validateUser)
.andThen(lookupCache) // <-- if lookupCache actually finds a result in the cache, we want to skip straight to the match() and return a response
.andThen(validateOptions)
.andThen(doSomethingExpensive)
.andThen(putInCache)
.match(result=>{
res.send(200,{status:"ok",result})
},err=>{
res.send(400,{status:"notok",error:err.message});
})
}
Basically.. I want to short circuit the pipeline if lookupCache
finds a result, but continue otherwise.
The only way I can see to do it without breaking this out into two pipelines.. is to return a special error and handle that in the error case..
Otherwise this is kinda what i'm doing now.. but it feels ugly somehow..
(req, res, next) => {
loadUser(req)
.andThen(validateUser)
.andThen(lookupCache)
.match(result =>{
if(result.isCacheHit){
res.send(200,{status:"ok",result});
return next();
}
validateOptions(result)
.andThen(doSomethingExpensive)
.andThen(putInCache)
.match(result=>{
res.send(200,{status:"ok",result})
},err=>{
res.send(400,{status:"notok",error:err.message});
})
},err=>{
res.send(400,{status:"notok",error:err.message})
})
}
it feels ugly because i'm doing the res.send
part in multiple places, when I just want to handle it in one .match
call..
Hello @cjroebuck
This is how I proceed
(req, res, next) => {
loadUser(req)
.andThen(validateUser)
.andThen(lookupCache)
.andThen((cache) => {
if(cache) return Ok(cache)
return validateOptions()
.andThen(doSomethingExpensive)
.andThen(putInCache)
})
.match(result=>{
res.send(200,{status:"ok",result})
},err=>{
res.send(400,{status:"notok",error:err.message});
})
}
I see.. thank you @paduc, that is a bit nicer!