ajel-go
What is ajel-go?
Ajel is a 312 byte set of functions that encourage you to handle errors in a way that is similar to Golang.
Installation
yarn add ajel-go eslint-plugin-ajel-go
pnpm add ajel-go eslint-plugin-ajel-go
Usage
// Handling async functions that throw
import { ajel } from 'ajel-go';
async function main() {
const [result, err] = await ajel(Promise.resolve('hello world'));
if (err) {
return err;
}
return result;
}
// Handling synchronous functions that throw
import { sjel } from 'ajel-go';
function main() {
const [result, err] = sjel(JSON.parse)("{}");
if (err) {
return err;
}
return result;
}
ajel
and sjel
are a set of functions that return a tuple representing a potential result and potential error.
On success, the result item has value. On error, the error item has value. It's that simple.
More interestingly, they come with a series of linting tools to help enforce the paradigm available in the package eslint-plugin-ajel
Basic eslintrc
{
plugins: ['ajel'],
extends: [
'plugin:ajel/recommended',
],
}
Why I ported Golang's most hated feature to JavaScript
As I entered yet another year of employment at my current company, I was tasked with a new goal. I wanted to learn something new. A little mustached Netflix birdie told me to dig one level deeper. I told myself it was time to stop being a lowly Typescript soy latte dev, and alas, I had a brief but impactful affair with the oxidized language Rust. As work demands kicked into overdrive during the busy portion of the year, I returned to Typescript land with my new experience with Result types - and I saw nothing but holes everywhere.
It greatly bothered me that I had never fully considered how to properly handle errors in my code. Thus began my
exploration of the topic.
It was not hard to narrow down the source of the problem. try/catch
is a terrible way to handle errors. More specifically, the problem is the throw
keyword is
not included in the type system, and thus, it is not possible to know what errors a function can throw.
I tried a few different approaches. Result-type libraries felt like trying to force Rust's paradigm into a language that wasn't designed for it. I wanted to find a way to with the language, not against it. Out of the solutions I tried, one of them felt right. (opens in a new tab) I had found a way that worked for me. And so, I decided to make a library out of it.