Error Handling

This guide will show you how to handle errors on Lens.


Lens tools categorize errors as either failures or exceptions:

  • Failure: A known issue directly related to business logic prevents the task from completing successfully. These scenarios are anticipated and managed within the application.

  • Exception: An unexpected issue arises, such as incorrect usage, invariant errors, or external/system malfunctions, which are not tied to business logic.

The Lens SDK adopts a functional approach to error handling. At its core, it uses a Result<T, E> object as the return value for many of its functions. This object can represent one of two states:

  • Ok<T>: A successful result containing a value of type T.

  • Err<E>: A failure containing an error of type E.

Any error thrown should be considered an exception—a malfunction not contemplated by the code.

This approach avoids reliance on try/catch blocks and promotes predictable, type-safe code by ensuring errors are handled explicitly.

Specifically, the SDK uses the NeverThrow library, which is re-exported for convenience.

import { Result, Ok, Err, ok, err } from "@lens-protocol/react";

Let’s explore the concept with a simple example function:

function parseNumber(input: string): Result<number, string> {  return isNaN(Number(input)) ? err("Invalid number") : ok(Number(input));}

You can use the convenient isOk() or isErr() methods to narrow down the result type:

Type Narrowing
const result = parseNumber("42");
if (result.isOk()) {  console.log("Number:", result.value);} else {  console.error("Error:", result.error);}

You can chain multiple operations:

Chaining
function divide(a: number, b: number): Result<number, string> {  return b === 0 ? err("Division by zero") : ok(a / b);}
const result = parseNumber("42").andThen((num) => divide(num, 2));
if (result.isOk()) {  console.log("Result:", result.value);} else {  console.error("Error:", result.error);}

You can also provide a default value:

Default Value
const value = parseNumber("invalid").unwrapOr(0); // 0

NeverThrow also provides a ResultAsync type for handling asynchronous operations. This is a thenable object that can be awaited, and/or chained with other operations:

Async
const result = await ResultAsync.fromPromise(  fetch("https://api.example.com/data"))  .map((response) => response.json())  .mapErr((error) => `Failed to fetch data: ${error}`);
if (result.isOk()) {  console.log("Data:", result.value);} else {  console.error("Error:", result.error);}

See the NeverThrow documentation for more information.