Skip to content

Instantly share code, notes, and snippets.

@superamadeus
Last active March 7, 2019 18:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save superamadeus/e81c0524d6991c6977cb4ab34b82321a to your computer and use it in GitHub Desktop.
Save superamadeus/e81c0524d6991c6977cb4ab34b82321a to your computer and use it in GitHub Desktop.
Informal "try expression" proposal
/**
* Proposal: Try expression.
* Goal: Facilitate imperative exception handling
*/
// Current exception handling pattern
try {
const user = await userRepo.getUserById(1);
console.log(`Hello, ${user.name}!`);
} catch (e) {
console.warn(e.message);
}
// Desired exception handling pattern
const [user, getUserFailed] = try await userRepo.getUserById(1);
if (!getUserFailed) {
console.log(`Hello, ${user.name}!`)
} else {
console.warn(getUserFailed.exception.message);
}
// Edit: examples not using await:
const books = [
{ author: "Brandon", title: "Magic Numbers"},
{ author: "Anthony", title: "Stupid Numbers"},
]
function getBookAuthorOrThrow(id) {
const book = books[id];
if (book == null) {
throw new Error(`Could not find book with this id (${id})`);
}
return book.author;
}
function sayHelloToBookAuthor(bookId) {
const [bookAuthor, getBookAuthorFailed] = getBookAuthorOrThrow(bookId);
if (!getBookAuthorFailed) {
console.log(`Hello, ${bookAuthor}!`);
} else {
console.log(console.log(getBookAuthorFailed.exception.message))
}
}
sayHelloToBookAuthor(1); // output: Hello, Brandon!
sayHelloToBookAuthor(100); // output: Could not find book with id (100).
// Simpler example:
const result1 = try 100;
const result2 = try (() => { throw new Error() })();
console.log(result1); // [100, undefined];
console.log(result2); // [undefined, TryFailure { exception: Error }];
// Approximate implementation with current features
class TryFailure {
constructor(exception) {
this.exception = exception;
}
}
function _try(fn) {
try {
const result = fn();
if (_isPromise(result)) {
return _tryAsync(result);
}
return _trySuccess(result);
} catch (e) {
return _tryFailure(e);
}
}
async function _tryAsync(promise) {
try {
return _trySuccess(await promise);
} catch (e) {
return _tryFailure(e);
}
}
function _isPromise(o) {
return o != null && typeof o.then === "function";
}
function _trySuccess(result) {
return [result, undefined]
}
function _tryFailure(exception) {
return [undefined, new TryFailure(exception)]
}
const [user, getUserFailed] = await _try(() => userRepo.getUserById(1));
// Edit: examples not using await:
function getBookOrThrow(id) {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment