--- banner: "https://media.discordapp.net/attachments/1050995657797816341/1091278921972064336/Triston_control_flow_a42cae90-667c-465d-9112-8104d61d0533.png?width=1856&height=1040" --- up:: [[JavaScript]] tags:: ## The Problem The Try/Catch flow can get really hairy with multiple requests becoming many lines of logic, like so: ```js let res1 try{ res1 = await request1() }catch(e){ // handle some error } let res2 try{ res2 = await request2() }catch(e){ // handle some error } let res3 try{ res3 = await request3() }catch(e){ // handle some error } ``` As well as the promise chaining can get nasty as well, like so: ```js request1().then(res => { requst2().then(res => { requst3().then(res => { // do something }).catch(e => console.error(e)) }).catch(e=>console.error(e)) }).catch(e => console.error(e)) ``` #### not ideal.. But theres a solution, that isnt my idea but i wanted to note it --- ## The solution We can create a single function that acts as a wrapper for the request and return a dictionary of value and error, like so: ```js export default async function result(cb){ let result = { value: null, error: null }; try { const r = await cb(); result.value = r; } catch (error) { result.error = error; } return result; } ``` and we can now use this function like so: ```js const {value, error} = await result(request1) ``` we dont need to wrap this in a try/catch because it will not fail And we can even alias the error and value if needing to make multiple async calls ```js const {value: aVal, error: aErr} = await result(request1) const {value: bVal, bErr} = await result(request2) const {value: cVal, cErr} = await result(request3) ``` Well, what if we need to pass `aVal` to `request2` EASY ```js const {value: aVal, error: aErr} = await result(request1) const {value: bVal, bErr} = await result(async () => await request2(aVal)) const {value: cVal, cErr} = await result(async () => await request3(bVal)) ``` And what if we need to control flow, maybe early return? Again, EASY ```js const {value: aVal, error: aErr} = await result(request1) if (aErr) return const {value: bVal, bErr} = await result(async () => await request2(aVal)) if (!bVal) return const {value: cVal, cErr} = await result(async () => await request3(bVal)) if (!cErr) return cVal if (cErr) return "whole thing failed" ``` --- ## Types Maybe we're using typescript and want to make this all type safe, cause right now, we know nothing