Last active
October 17, 2017 21:57
-
-
Save mikermcneil/c1bc2d57f5bedae810295e5ed8c5f935 to your computer and use it in GitHub Desktop.
Some demonstrative examples of early returns with promises/`async`+`await` in synchronous vs. asynchronous usage. (This is mostly about weighing the pros and cons of `.unless()`.)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
await User.create({ | |
emailAddress: 'asdf@asdf.com' | |
}) | |
.unless('E_UNIQUE', ()=>{ | |
return exits.conflict() | |
}); | |
return exits.success(); | |
try { | |
await User.create({ | |
emailAddress: null.emailAddress | |
}); | |
} catch (err) { | |
switch (err.code) { | |
case 'E_UNIQUE': | |
return exits.conflict(); | |
default: | |
throw err; | |
} | |
} | |
return exits.success(); | |
User.parse({ | |
emailAddress: 'asdfasdf@asdggasd.com' | |
}) | |
.unless({ name: 'UsageError' }, (err)=>{ | |
return exits.badRequest(err); | |
}) | |
.execSync(); | |
return exits.success(); | |
try { | |
User.parse({ | |
emailAddress: null.emailAddress | |
}); | |
} catch (err) { | |
switch (err.name) { | |
case 'UsageError': | |
return exits.badRequest(err); | |
default: | |
throw err; | |
} | |
} | |
return exits.success(); | |
For posterity, some additional related notes from flaverr
:
And from parley
:
More related notes from CloudSDK:
// - - - - - - - - - - - - - - - - - - - - - - - - - - -
// ```
// .intercept(404, (err)=>flaverr({ name: 'UsageError' }, err))
// ```
//
// ```
// .intercept('notFound', (err)=>flaverr({ name: 'UsageError' }, err))
// ```
//
// ```
// .intercept({name: 'AdapterError'}, (err)=>flaverr({ name: 'UsageError' }, err))
// ```
//
// .intercept()
// ^^ useful for catching, augmenting, and then rethrowing certain errors
// ^^ you must return an Error instance from the function
// (If you return anything else, or don't return -- aka return undefined
// -- then it'll be considered an inverse-implementation error and handled
// accordingly)
// ^^ you should NOT rethrow. It'll happen automatically.
// (If you rethrow, it'll be considered an inverse-implementation error
// and handled accordingly.)
//
//
// •••• •••• •••• •••• •••• •••• •••• •••• •••• •••• •••• ••••
//
// ```
// .tolerate(404)
// ```
//
// ```
// .tolerate(404, ()=>{ window.location = '/login'; })
// ```
//
// ```
// .tolerate('E_INVALID_ARGINS', (err)=>{ this.formErrors = err.map; })
// ```
//
// ```
// .tolerate((err)=>{ if (!err.exit) { throw err; } this.formCloudError = err.exit; } })
// ```
//
// .tolerate()
// ^^ does not throw again by default, so useful for reconverging after certain errors
// ^^ whatever you `return` gets sent back as the return value for the function
// ^^ If you passed in a first argument, you should NOT rethrow. If you rethrow, it'll
// be considered an inverse-implementation error and handled accordingly. (If you omit
// the "rule" argument, it makes sense to be able to rethrow. But as usual, whenever
// omitting the "rule" argument, just be careful-- it's easy to swallow errors this way
// if you don't carefully inspect the error!)
// ^^ can also be used to accomplish the avast thing
// - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
OK after much experimentation here, I think it's safe to say this is too much magic-- specifically the bit about making the userland environment aware of the "Avast" aka early return signal. Probably better to avoid the try/catch swallowing issue by being explicit and taking advantage of closure scope, e.g.: