Errors

Every Macrofy error — whether from the API or the SDK — is designed to be actionable. The API returns structured JSON; the SDK wraps it in a typed ApiError you can switch on without parsing strings.


Error shape

API response

All error responses from the Macrofy API share the same shape:

Error response

{
  "error": "Human-readable error message"
}

SDK exception

The @macrofy/react-native SDK wraps API errors (and client-side failures) into an ApiError class:

ApiError

import { ApiError } from '@macrofy/react-native'

// Properties
error.message    // string — human-readable description
error.code       // ApiErrorCode — typed constant (e.g. "UNAUTHORIZED")
error.statusCode // number | undefined — HTTP status when server-originated
error.details    // unknown — raw server payload, if any

HTTP status reference

  • Name
    200
    Type
    OK
    Description

    Request succeeded. Response contains the requested resource.

  • Name
    400
    Type
    Bad Request
    Description

    The request body failed validation (missing fields, malformed ID, etc.).

  • Name
    401
    Type
    Unauthorized
    Description

    Signature verification failed. The HMAC does not match HMAC-SHA256(appSecret, userId).

  • Name
    403
    Type
    Forbidden
    Description

    Sandbox quota exceeded. Your application has reached its monthly active user limit (default: 10).

  • Name
    404
    Type
    Not Found
    Description

    The requested application or resource does not exist.

  • Name
    5xx
    Type
    Server Error
    Description

    Unexpected platform error. Retry with exponential backoff.

401 — Invalid signature

401 example

{
  "error": "Invalid signature"
}

Double-check that your backend is signing the exact userId string with the correct appSecret, and that the signature is a 64-character lowercase hex string.

403 — Sandbox quota exceeded

403 example

{
  "error": "Sandbox quota exceeded. Your application has reached its limit of 10 users."
}

Existing users who were previously mapped will continue to work. This error only occurs when attempting to connect a new external user beyond the limit.


SDK error codes

The SDK surfaces a typed code on every ApiError. Import the constants from @macrofy/react-native:

Import

import { API_ERROR_CODES } from '@macrofy/react-native'
  • Name
    CONFIGURATION_ERROR
    Type
    client-side
    Description

    A required adapter was not provided. For example, calling connect() without a StorageAdapter.

  • Name
    STORAGE_ERROR
    Type
    client-side
    Description

    Session persistence failed (e.g. the StorageAdapter threw during a write). The SDK rolls back in-memory state automatically.

  • Name
    IMAGE_READ_FAILED
    Type
    client-side
    Description

    The FileSystemAdapter failed to read an image file.

  • Name
    VALIDATION_ERROR
    Type
    client-side
    Description

    Input failed local validation before a network request was made (empty appId, invalid format, signature not 64 chars, etc.).

  • Name
    UNAUTHORIZED
    Type
    HTTP 401
    Description

    Signature does not match. Verify your backend HMAC generation.

  • Name
    QUOTA_EXCEEDED
    Type
    HTTP 403
    Description

    Sandbox user limit reached. Do not retry automatically.

  • Name
    NOT_FOUND
    Type
    HTTP 404
    Description

    Application not found. Check your appId.

  • Name
    NETWORK_ERROR
    Type
    client-side
    Description

    Device is offline or the server is unreachable. Safe to retry.

  • Name
    TIMEOUT
    Type
    client-side
    Description

    Request exceeded the 30-second timeout. Safe to retry.

  • Name
    SERVER_ERROR
    Type
    HTTP 5xx
    Description

    Unexpected server error. Retry with backoff.


Handling patterns

Recommended approach

Error handling

import { ApiError, API_ERROR_CODES } from '@macrofy/react-native'

try {
  await macrofy.connect({ appId, userId, signature })
} catch (error) {
  if (!(error instanceof ApiError)) throw error

  switch (error.code) {
    case API_ERROR_CODES.VALIDATION_ERROR:
      // Show inline form validation
      break
    case API_ERROR_CODES.UNAUTHORIZED:
      // Prompt user to re-check credentials
      break
    case API_ERROR_CODES.QUOTA_EXCEEDED:
      // Show upgrade prompt — do NOT retry
      break
    case API_ERROR_CODES.NETWORK_ERROR:
    case API_ERROR_CODES.TIMEOUT:
      // Show "try again" — safe to retry
      break
    case API_ERROR_CODES.SERVER_ERROR:
      // Show generic error — retry with backoff
      break
  }
}

Retry guidance

  • Name
    Safe to retry
    Description

    NETWORK_ERROR, TIMEOUT, SERVER_ERROR. Use exponential backoff for server errors.

  • Name
    Do NOT retry
    Description

    VALIDATION_ERROR, UNAUTHORIZED, QUOTA_EXCEEDED. These require user or developer action to resolve.

Was this page helpful?