Skip to main content
The SDK exports three error classes you can use to identify and handle failures precisely.

Error classes

import { WrapsEmailError, ValidationError, SESError } from '@wraps.dev/email';

try {
  await email.send({ /* ... */ });
} catch (error) {
  if (error instanceof ValidationError) {
    console.error('Invalid input:', error.field, error.message);
  } else if (error instanceof SESError) {
    console.error('SES error:', error.code, error.retryable);
  }
}

WrapsEmailError

Base error class. All SDK errors extend this class. Use it to catch any SDK-originated error without distinguishing the type.
import { WrapsEmailError } from '@wraps.dev/email';

try {
  await email.send({ /* ... */ });
} catch (error) {
  if (error instanceof WrapsEmailError) {
    // Any SDK error
    console.error(error.message);
  }
}

ValidationError

Thrown when input fails validation before the request reaches SES. Check error.field to identify which parameter is invalid.
PropertyTypeDescription
fieldstringThe parameter name that failed validation (e.g. 'from', 'to').
messagestringHuman-readable description of the validation failure.
import { ValidationError } from '@wraps.dev/email';

try {
  await email.send({ /* ... */ });
} catch (error) {
  if (error instanceof ValidationError) {
    console.error(`Invalid field '${error.field}': ${error.message}`);
  }
}

SESError

Thrown when AWS SES returns an error. Check error.retryable to determine whether the operation can be retried.
PropertyTypeDescription
codestringAWS error code returned by SES (e.g. 'MessageRejected', 'Throttling').
retryablebooleantrue if the error is transient and the request can be retried.
import { SESError } from '@wraps.dev/email';

try {
  await email.send({ /* ... */ });
} catch (error) {
  if (error instanceof SESError) {
    if (error.retryable) {
      // Implement exponential backoff and retry
    } else {
      console.error('Permanent SES error:', error.code);
    }
  }
}

Common errors and fixes

Error: ValidationErrorfrom address is not verified in SES.Fix: Your from address must belong to a domain you have verified in SES. Add and verify your domain:
wraps email domains add -d yourapp.com
wraps email domains verify -d yourapp.com
Error: SESError with code: 'Throttling' and retryable: true.Fix: Implement exponential backoff when error.retryable is true.
import { SESError } from '@wraps.dev/email';

async function sendWithRetry(params: SendParams, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await email.send(params);
    } catch (error) {
      if (error instanceof SESError && error.retryable && attempt < maxRetries - 1) {
        await new Promise((resolve) => setTimeout(resolve, 2 ** attempt * 500));
      } else {
        throw error;
      }
    }
  }
}
Error: ValidationError with field: 'to' or field: 'from'.Fix: Ensure all email addresses are valid RFC 5321 addresses. Validate user input before passing it to send().
Error: SESError with code: 'MessageRejected' — recipient address is not verified.Fix: New AWS accounts start in SES sandbox mode, where you can only send to verified email addresses or the SES mailbox simulator. To send to any recipient, request production access:
  1. Open the SES console.
  2. Choose Request production access.
  3. Complete the form. Approval typically takes up to 24 hours.
In the meantime, verify destination addresses for testing:
wraps email domains add -d yourtestdomain.com
wraps email domains verify -d yourtestdomain.com

Build docs developers (and LLMs) love