Skip to main content

Overview

The Cuey TypeScript client provides typed error classes for different error scenarios. All errors extend from CueyError and include status codes and error details.

Error Classes

CueyError

Base error class for all Cuey API errors.
CueyError
class
Base error class extending JavaScript’s Error.

UnauthorizedError (401)

Thrown when the API key is invalid or missing.
UnauthorizedError
class
Extends CueyError. Thrown when authentication fails.

NotFoundError (404)

Thrown when a requested resource doesn’t exist.
NotFoundError
class
Extends CueyError. Thrown when a resource is not found.

BadRequestError (400)

Thrown when the request is invalid (e.g., trying to update a non-pending event).
BadRequestError
class
Extends CueyError. Thrown when the request is invalid.

ValidationError (400)

Thrown when request validation fails. Includes detailed validation errors.
ValidationError
class
Extends CueyError. Thrown when request validation fails.

InternalServerError (500+)

Thrown when a server error occurs (e.g., requesting an out-of-range page).
InternalServerError
class
Extends CueyError. Thrown when a server error occurs.

Error Codes

CueyErrorCode
union
Union type of all possible error codes.

Basic Error Handling

Try-Catch Pattern

import {
  CueyError,
  UnauthorizedError,
  NotFoundError,
  ValidationError,
  BadRequestError,
  InternalServerError,
} from "cuey";

try {
  const cron = await cuey.crons.get("invalid-id");
} catch (error) {
  if (error instanceof NotFoundError) {
    console.error("Cron not found:", error.message);
  } else if (error instanceof UnauthorizedError) {
    console.error("Authentication failed:", error.message);
  } else if (error instanceof CueyError) {
    console.error("API error:", error.code, error.message);
  } else {
    console.error("Unknown error:", error);
  }
}

Handling Validation Errors

Validation errors include detailed information about what failed:
import { ValidationError } from "cuey";

try {
  const event = await cuey.events.create({
    webhook_url: "invalid-url", // Invalid URL
    scheduled_at: "2020-01-01T00:00:00Z", // In the past
    method: "INVALID", // Invalid method
  });
} catch (error) {
  if (error instanceof ValidationError) {
    console.error("Validation failed:", error.message);
    console.error("Validation errors:", error.validationErrors);
    // Example output:
    // [
    //   { path: ["webhook_url"], message: "Invalid URL" },
    //   { path: ["scheduled_at"], message: "Must be in the future" },
    //   { path: ["method"], message: "Invalid HTTP method" }
    // ]
  }
}

Common Error Scenarios

Invalid API Key

import { Cuey, UnauthorizedError } from "cuey";

try {
  const cuey = new Cuey({ apiKey: "invalid-key" });
  await cuey.crons.list();
} catch (error) {
  if (error instanceof UnauthorizedError) {
    console.error("Invalid API key. Please check your credentials.");
  }
}

Resource Not Found

import { NotFoundError } from "cuey";

try {
  const cron = await cuey.crons.get("non-existent-id");
} catch (error) {
  if (error instanceof NotFoundError) {
    console.error("Cron job not found");
    // Handle: show user-friendly message, redirect, etc.
  }
}

Invalid Request Data

import { ValidationError, BadRequestError } from "cuey";

try {
  const event = await cuey.events.create({
    webhook_url: "https://api.example.com/webhook",
    scheduled_at: "2020-01-01T00:00:00Z", // In the past
  });
} catch (error) {
  if (error instanceof ValidationError) {
    // Handle validation errors
    console.error("Invalid input:", error.validationErrors);
  } else if (error instanceof BadRequestError) {
    // Handle other bad request errors
    console.error("Bad request:", error.message);
  }
}

Updating Non-Pending Event

import { BadRequestError } from "cuey";

try {
  // Try to update an event that's already executed
  await cuey.events.update("event-id", {
    webhook_url: "https://api.example.com/webhook",
    scheduled_at: "2025-01-01T00:00:00Z",
  });
} catch (error) {
  if (error instanceof BadRequestError) {
    console.error("Cannot update:", error.message);
    // Error message: "Only pending events can be updated"
  }
}

Out of Range Pagination

import { InternalServerError } from "cuey";

try {
  // Request page 1000 when only 10 pages exist
  await cuey.crons.list({ page: 1000 });
} catch (error) {
  if (error instanceof InternalServerError) {
    console.error("Page out of range");
    // Handle: reset to page 0, show error message, etc.
  }
}

Error Handling Utilities

Generic Error Handler

import { CueyError } from "cuey";

function handleCueyError(error: unknown): void {
  if (error instanceof CueyError) {
    switch (error.code) {
      case "UNAUTHORIZED":
        console.error("Authentication failed. Please check your API key.");
        break;
      case "NOT_FOUND":
        console.error("Resource not found.");
        break;
      case "VALIDATION_ERROR":
        console.error("Validation failed:", error.validationErrors);
        break;
      case "BAD_REQUEST":
        console.error("Invalid request:", error.message);
        break;
      case "INTERNAL_SERVER_ERROR":
        console.error("Server error:", error.message);
        break;
    }
  } else {
    console.error("Unknown error:", error);
  }
}

try {
  await cuey.crons.list();
} catch (error) {
  handleCueyError(error);
}

Retry on Specific Errors

import { InternalServerError } from "cuey";

async function retryOnServerError<T>(
  fn: () => Promise<T>,
  maxRetries = 3
): Promise<T> {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (error instanceof InternalServerError && i < maxRetries - 1) {
        console.log(`Retry ${i + 1}/${maxRetries}...`);
        await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1)));
        continue;
      }
      throw error;
    }
  }
  throw new Error("Max retries exceeded");
}

// Usage
const crons = await retryOnServerError(() => cuey.crons.list());

Error Type Guards

import { CueyError, ValidationError } from "cuey";

function isCueyError(error: unknown): error is CueyError {
  return error instanceof CueyError;
}

function isValidationError(error: unknown): error is ValidationError {
  return error instanceof ValidationError;
}

// Usage
try {
  await cuey.events.create({ ... });
} catch (error) {
  if (isValidationError(error)) {
    // Handle validation errors specifically
    console.error("Validation failed:", error.validationErrors);
  } else if (isCueyError(error)) {
    // Handle other Cuey errors
    console.error("Cuey error:", error.code, error.message);
  } else {
    // Handle unknown errors
    console.error("Unknown error:", error);
  }
}

Best Practices

Always Handle Errors

import { NotFoundError } from "cuey";

// ❌ Bad: Unhandled errors
const cron = await cuey.crons.get("id");

// ✅ Good: Proper error handling
try {
  const cron = await cuey.crons.get("id");
} catch (error) {
  if (error instanceof NotFoundError) {
    // Handle not found
  } else {
    // Handle other errors
  }
}

Provide User-Friendly Messages

import { ValidationError, UnauthorizedError } from "cuey";

try {
  await cuey.events.create({ ... });
} catch (error) {
  if (error instanceof ValidationError) {
    // Extract user-friendly messages from validation errors
    const messages = (error.validationErrors as Array<{ message: string }>)
      .map((e) => e.message)
      .join(", ");
    showError(`Please fix the following: ${messages}`);
  } else if (error instanceof UnauthorizedError) {
    showError("Please check your API key in settings.");
  } else {
    showError("An unexpected error occurred. Please try again.");
  }
}

Importing Error Classes

import {
  CueyError,
  UnauthorizedError,
  NotFoundError,
  BadRequestError,
  ValidationError,
  InternalServerError,
} from "cuey";