cimplify
Concepts

Result

Every SDK method returns `Result<T, CimplifyError>` and never throws. You narrow on `.ok`, and TypeScript gives you either `value` or `error` on the other branch.

The shape

type Result<T, E = CimplifyError> =
  | { ok: true;  value: T }
  | { ok: false; error: E };

Narrowing

Check r.ok first. Inside the truthy branch r.value is typed; inside the falsy branch r.error is typed. Trying to read the wrong one is a compile error.

const r = await client.catalogue.getProducts({ limit: 24 });

if (!r.ok) {
  // r.error is CimplifyError here
  console.error(r.error.code, r.error.message);
  return;
}

// r.value is { items, pagination } here
for (const product of r.value.items) {
  console.log(product.name);
}

Why no exceptions

Network failures, validation errors, rate limits, and business-rule violations are all expected outcomes of a request, not exceptional control flow. Forcing callers to wrap every call in try/catch hides the failure modes from the type system. A Result makes them visible: you cannot read value without also handling error.

try / catchResult
Errors are invisible until runtimeFailure is part of the return type
Forgetting catch crashes the pageForgetting !r.ok is a compile error
Mixed sync/async error handlingOne branch, same shape, every call
Stack traces with no domain contextcode, retryable, context

In React components

Hooks like useProducts unwrap the Result for you and surface { data, error, isLoading }. When you call the client directly inside an effect or a server action, narrow the same way you would on the server.

Inside a Server Action
"use server";
import { getServerClient } from "@cimplify/sdk/server";

export async function applyCoupon(code: string) {
  const r = await getServerClient().cart.applyCoupon(code);
  if (!r.ok) {
    return { ok: false, message: r.error.message };
  }
  return { ok: true, cart: r.value };
}

Composing Results

For a sequence of dependent calls, fail early on the first error. Don't try to recreate Promise chaining; straight-line code with early returns is the readable form.

async function placeFirstOrder() {
  const products = await client.catalogue.getProducts({ limit: 1 });
  if (!products.ok) return products;

  const first = products.value.items[0];
  if (!first) return { ok: false as const, error: new Error("empty catalogue") };

  const added = await client.cart.addItem({ item_id: first.id, quantity: 1 });
  if (!added.ok) return added;

  const cart = await client.cart.get();
  if (!cart.ok) return cart;

  return client.checkout.process({
    cart_id: cart.value.id,
    customer: { name: "Akua", email: "akua@example.com", phone: "+233244000000" },
    order_type: "delivery",
    payment_method: "mobile_money",
  });
}

Next

On this page