README
goerr
handle throwing errors in golang way
Install
# install with npm
npm add goerr
# install with yarn
yarn add goerr
Import
// ES Module
import goerr from 'goerr'
// CommonJS
const goerr = require('goerr')
Usage
Handle A Synchronous Function Calling
goerr
method expects a function (especially a lambda expression) as the argument, in which calling some throwable functions and returning a value.
The value will be the first element of an array returned by goerr
. Any error throwed when calling the function will be the second element of the array.
Note: You can not return a Promise
object in the throwableFunction
. If you really want to handle asynchronous errors, see next part.
API
function goerr<T>(func: () => T): [T, Error]
Example
const [result, err] = goerr(() => throwableFunction())
if (err) {
// do something here
}
// go ahead with the result
console.log(result)
Handle An Asynchronous Promise
goerr
can aslo accept a Promise
object in order to handle cases you have to do asynchronously.
API
function goerr<T>(promise: Promise<T>): Promise<[T, Error]>
Example
const [result, err] = await goerr(axios.get('https://example.com'))
if (err) {
// do something here
}
// go ahead with the result
console.log(result)
Why This
Background
Since we all know that try
/catch
works good in JavaScript, you might be confused about if we really need to handle errors in golang way.
Suppose now we are writing a function to return a list coming from a throwable function, and we think returing an empty list when an error throwed would be better.
How could we do?
Solution 1
function listOf() {
try {
const list = throwable()
return list
} catch (_) {
return []
}
}
It looks good, but what if we need to do some operations on this list?
Solution 2
function listOf() {
try {
const list = throwable()
for (let item of list) {
// do something with items
}
return list
} catch (_) {
return []
}
}
Good job! But if we have a better choise?
Solution 3
The defect of solution 2 is about code smell. We should return as soon as we can to avoid nested code.
function listOf() {
const [list, err] = goerr(throwable)
if (err) {
return []
}
for (let item of list) {
// do something with items
}
return list
}
Now you see the for
loop becomes the top level of the function. It looks more clear, right?