Error Handling

Turbine provides a custom error class and clear error messages to help you debug issues.

TurbineError

All Turbine-specific errors are instances of TurbineError:

import { TurbineError } from "dynamodb-turbine";

try {
  await users.put({ id: "123" }); // Missing required field
} catch (error) {
  if (error instanceof TurbineError) {
    console.error("Turbine error:", error.message);
  }
}

Common Error Scenarios

Schema Validation Errors

When data doesn't match your Zod schema:

const users = defineEntity({
  table,
  schema: z.object({
    id: z.string(),
    email: z.string().email(),
    age: z.number().min(0),
  }),
  keys: { /* ... */ },
});

// Missing required field
await users.put({ id: "123" });
// Error: Required field 'email' is missing

// Invalid email format
await users.put({ id: "123", email: "not-an-email" });
// Error: Invalid email

// Invalid number
await users.put({ id: "123", email: "a@b.com", age: -5 });
// Error: Number must be greater than or equal to 0

Invalid Index

When querying a non-existent index:

const table = defineTable({
  name: "my-table",
  indexes: {
    table: { hashKey: "pk", rangeKey: "sk" },
    gsi1: { hashKey: "type" },
  },
});

// Querying undefined index
await users.query({
  index: "gsi2", // Does not exist
  // ...
});
// Error: Index 'gsi2' is not defined

Missing Key Fields

When query keys don't match the index:

// Index requires 'type' as hash key
await users.query({
  index: "gsi1",
  // Missing 'type' field
});
// Error: Missing required key 'type' for index 'gsi1'

Error Handling Patterns

Try-Catch

async function createUser(data: UserInput) {
  try {
    return await users.put(data);
  } catch (error) {
    if (error instanceof TurbineError) {
      // Handle validation or configuration errors
      throw new Error(`Invalid user data: ${error.message}`);
    }
    // Re-throw other errors (network, permissions, etc.)
    throw error;
  }
}

Checking Existence

async function getUserOrThrow(id: string) {
  const user = await users.get({
    pk: ["user", id],
    sk: "profile",
  });

  if (!user) {
    throw new Error(`User not found: ${id}`);
  }

  return user;
}

Handling DynamoDB Errors

DynamoDB client errors are passed through:

import { ConditionalCheckFailedException } from "@aws-sdk/client-dynamodb";

try {
  await users.put(data);
} catch (error) {
  if (error instanceof TurbineError) {
    // Turbine validation error
  } else if (error instanceof ConditionalCheckFailedException) {
    // DynamoDB condition failed
  } else {
    // Other errors (network, permissions)
  }
}

Validation Before Operations

Use Zod's parse methods for pre-validation:

const userSchema = z.object({
  id: z.string(),
  email: z.string().email(),
  name: z.string(),
});

function validateUserInput(data: unknown) {
  const result = userSchema.safeParse(data);

  if (!result.success) {
    // Handle validation errors with detailed info
    const errors = result.error.issues.map(issue => ({
      field: issue.path.join("."),
      message: issue.message,
    }));
    return { success: false, errors };
  }

  return { success: true, data: result.data };
}

Debugging Tips

Enable Logging

Log operations for debugging:

async function putWithLogging<T>(entity: Entity<any>, data: T) {
  console.log("PUT:", JSON.stringify(data, null, 2));

  try {
    const result = await entity.put(data);
    console.log("SUCCESS:", result);
    return result;
  } catch (error) {
    console.error("ERROR:", error);
    throw error;
  }
}

Check Key Values

Verify generated keys:

const users = defineEntity({
  table,
  schema: z.object({ /* ... */ }),
  keys: {
    pk: (u) => {
      const key = ["user", u.id];
      console.log("Generated pk:", key);
      return key;
    },
    sk: (u) => u.email,
  },
});

Inspect DynamoDB Items

Check what's actually stored:

const user = await users.put({
  id: "123",
  email: "alice@example.com",
  name: "Alice",
});

// The instance includes all attributes
console.log("Stored item:", {
  pk: user.pk,   // "user#123"
  sk: user.sk,   // "alice@example.com"
  id: user.id,
  email: user.email,
  name: user.name,
});

Error Reference

ErrorCauseSolution
Schema validation failedData doesn't match Zod schemaCheck required fields, types, and constraints
Index not definedQuery uses unknown index nameVerify index exists in defineTable
Missing key fieldQuery missing required keyInclude all hash/range keys for the index
Invalid key valueKey function returned invalid valueCheck key functions return strings, numbers, or arrays

Next Steps