essiet2002@gmail.com

Embracing Rust-Style Error Handling in JavaScript with try.rs

Explore how the try.rs library brings Rust-inspired error handling to JavaScript and TypeScript, enhancing code readability and maintainability. - 11/04/2025

JavaScript’s error handling has long been a source of frustration for developers. The traditional try/catch mechanism often leads to verbose and tangled code, making it challenging to manage errors effectively. Enter try.rs, a TypeScript library that brings Rust-like error handling to JavaScript and TypeScript, offering a more structured and readable approach.

1. The Problem with JavaScript’s Error Handling

The try...catch syntax has served JavaScript developers for years, but it often leads to certain challenges:

try {
  const result = someFunction();
  try {
    const processed = anotherFunction(result);
  } catch (error) {
    console.error("Error in anotherFunction:", error);
  }
} catch (error) {
  console.error("Error in someFunction:", error);
}

2. Possible Solutions to Improve Error Handling

Over the years, us developers have explored various approaches to improve error handling in JavaScript:

Promise .catch()

For asynchronous operations, Promises provide a .catch() method to handle errors. This is cleaner than nested try…catch blocks but still requires careful chaining to avoid missing errors.

fetchData()
  .then((data) => processData(data))
  .catch((error) => console.error("Error:", error));

Callback Pattern

In older Node.js code, the callback pattern was widely used, where functions explicitly passed an error as the first argument. While this avoids throwing exceptions, it can lead to “callback hell” and is less common in modern JavaScript code now.

fs.readFile("file.txt", (err, data) => {
  if (err) {
    console.error("Error reading file:", err);
    return;
  }
  console.log("File data:", data);
});

Go-style Error Returns

Inspired by Go, some of us use a pattern where functions return a tuple (or array) containing an error and a result. This makes errors explicit but requires manual checking after every call.

const [error, result] = mightFail();
if (error) {
  console.error("Error:", error);
} else {
  console.log("Result:", result);
}

Functional Error Handling

Libraries like fp-ts and neverthrow introduce functional programming concepts such as Either or Result types. These types explicitly represent success or failure as values, making error handling more predictable and composable.


3. Introducing try.rs: A Rust-Inspired Solution

try.rs is a TypeScript library that emulates Rust’s Result<T, E> type, providing a structured way to handle operations that may fail. It encourages the explicit handling of errors, leading to more predictable and maintainable code.

Key Features:


4. Practical Examples of try.rs in Action

Handling Synchronous Operations

import { ok, err } from 'try.rs';
function divide(a: number, b: number) {
  if (b === 0) {
    return err("Division by zero");
  }
  return ok(a / b);
}
const result = divide(10, 2);
result.match({
  ok: (value) => console.log(`Result: ${value}`),
  err: (error) => console.error(`Error: ${error}`),
});

Wrapping Functions That May Throw

import { tryFn } from 'try.rs';
const parseJson = (input: string) => tryFn(() => JSON.parse(input));

const result = parseJson('{"name": "Alice"}');

result.match({
  ok: (data) => console.log(`Parsed data: ${data.name}`),
  err: (error) => console.error(`Parsing error: ${error}`),
});

Managing Asynchronous Operations

import { tryAsync } from 'try.rs';
async function fetchData(url: string) {
  return tryAsync(async () => {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`HTTP error: ${response.status}`);
    }
    return response.json();
  });
}

async function main() {
  const result = await fetchData('https://api.example.com/data');
  result.match({
    ok: (data) => console.log('Data:', data),
    err: (error) => console.error('Error:', error),
  });
}

main();

Conclusion

try.rs offers a compelling alternative to traditional JavaScript error handling by introducing a Rust-inspired Result type. It promotes explicit and consistent error management, leading to cleaner and more reliable code. By integrating try.rs into your JavaScript or TypeScript projects, you can enhance your application’s robustness and maintainability.

For more information and to get started, visit the try.rs npm package page.