sharils-try v1.0.1
sharils-try
Problems
Let's look at the following snippet.
let data;
try {
data = JSOM.parse(json);
} catch (e) {
console.error("syntax error in the json string");
}
console.log(data);
This snippet has three problems:
- The console is printed "syntax error in the json string" however, it's triggered by the JSOM typo because a ReferenceError can be caught.
data
has to be declared usinglet
becausetry
is a blocke
is not available outside of thecatch
clause.
There is a awakard way to fix problem 1. See below:
let data;
try {
data = JSOM.parse(json);
} catch (e) {
if (e.constructor === ReferenceError) {
console.error("syntax error in the json string");
}
throw e;
}
Solution
const [e, data] = tryCall([ReferenceError], JSON.parse, json);
if (e) {
console.error("syntax error in the json string");
} else {
console.log(data);
}
This returns a sparse array for easy destructuring, and only one of the element will be set depending on the index of the error class if fail or set to the last index if succeed.
Philosophy
The reason errors exist before the call result is because this library thinks all errors should be handled, thus it's designed to make ignoring errors difficult. You can't easily get result without getting all errors.
The reason there is no flag to tell if there is no error thrown is also because of the same reason above.
Generator
There is tryYield
to do the same thing as tryCall
in a generator. Let's take the following snippet from redux-saga.
function* fetchUser(action) {
try {
const user = yield call(Api.fetchUser, action.payload.userId);
yield put({type: "USER_FETCH_SUCCEEDED", user: user});
} catch (e) {
yield put({type: "USER_FETCH_FAILED", message: e.message});
}
}
Using tryYield
, this can be written as the following:
function* fetchUser(action) {
const [e, user] = yield* tryYield([UserFetchError], call(Api.fetchUser, action.payload.userId));
if (e) {
yield put({type: "USER_FETCH_FAILED", message: e.message});
} else {
yield put({type: "USER_FETCH_SUCCEEDED", user: user});
}
}
Note that yield call
becomes yield* tryYield
. And call(Api.fetchUser, action.payload.userId)
is directly wrapped by tryYield
instead of tryYield(call, Api.fetchUser, action.payload.userId)
.
Test
yarn test
Build
yarn run build