NueForm

Manejo de errores

Comprende el formato de respuesta de error de la API de NueForm, los códigos de error y cómo manejar errores de forma elegante en tu aplicación.

La API de NueForm utiliza códigos de estado HTTP convencionales y devuelve respuestas de error JSON estructuradas. Esta guía cubre el formato de respuesta, todos los códigos de error posibles y patrones para manejar errores en tu código.

Formatos de respuesta

Respuestas exitosas

Las llamadas exitosas a la API devuelven un objeto JSON con un campo data. Los endpoints de lista también incluyen un campo meta con información de paginación.

json
{
  "data": {
    "id": "clx1abc2d3e4f5g6h7i8j9k0",
    "title": "Customer Feedback",
    "status": "published",
    "created_at": "2026-01-15T09:30:00.000Z"
  }
}

Con metadatos de paginación:

json
{
  "data": [
    {
      "id": "clx1abc2d3e4f5g6h7i8j9k0",
      "title": "Customer Feedback"
    },
    {
      "id": "clx2def3g4h5i6j7k8l9m0n1",
      "title": "Employee Survey"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 150,
    "total_pages": 8
  }
}

Respuestas de error

Las respuestas de error devuelven un objeto JSON con un campo error que contiene el code de error, un message legible para humanos y el código de status HTTP.

json
{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested form could not be found.",
    "status": 404
  }
}

Códigos de error

La siguiente tabla lista todos los códigos de error devueltos por la API:

CódigoEstado HTTPDescripción
BAD_REQUEST400La solicitud está mal formada, faltan campos requeridos o contiene valores inválidos.
UNAUTHORIZED401La autenticación falló. La clave de API falta, está mal formada, revocada o expirada.
FORBIDDEN403El usuario autenticado no tiene permiso para realizar esta acción.
NOT_FOUND404El recurso solicitado no existe o no es accesible para el usuario autenticado.
CONFLICT409La solicitud entra en conflicto con el estado actual del recurso (por ejemplo, entrada duplicada).
RATE_LIMITED429Demasiadas solicitudes. Consulta Límites de velocidad para más detalles.
INTERNAL_ERROR500Ocurrió un error inesperado en el servidor.

Ejemplos de respuestas de error

400 Bad Request

Se devuelve cuando el cuerpo de la solicitud es inválido o faltan campos requeridos.

json
{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Field 'title' is required.",
    "status": 400
  }
}

401 Unauthorized

Se devuelve cuando la autenticación falla por cualquier motivo.

json
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or expired API key.",
    "status": 401
  }
}

403 Forbidden

Se devuelve cuando el usuario está autenticado pero carece de permisos. Las causas comunes incluyen acceder a recursos de otro usuario o usar una función no disponible en el plan actual.

json
{
  "error": {
    "code": "FORBIDDEN",
    "message": "API access is not available on your current plan.",
    "status": 403
  }
}

404 Not Found

Se devuelve cuando el recurso solicitado no existe.

json
{
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested form could not be found.",
    "status": 404
  }
}

409 Conflict

Se devuelve cuando la solicitud crearía un duplicado o entra en conflicto con datos existentes.

json
{
  "error": {
    "code": "CONFLICT",
    "message": "A form with this slug already exists.",
    "status": 409
  }
}

429 Rate Limited

Se devuelve cuando se ha excedido el límite de velocidad. Incluye un encabezado Retry-After.

json
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Please try again later.",
    "status": 429
  }
}

500 Internal Error

Se devuelve cuando ocurre un error inesperado del servidor. Si persiste, contacta con soporte.

json
{
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "An internal error occurred.",
    "status": 500
  }
}

Manejo de errores en código

JavaScript

Construye un cliente de API reutilizable que verifique errores y lance excepciones tipadas:

javascript
class NueFormApiError extends Error {
  constructor(code, message, status) {
    super(message);
    this.name = "NueFormApiError";
    this.code = code;
    this.status = status;
  }
}

async function nueformRequest(path, options = {}) {
  const response = await fetch(`https://app.nueform.com/api/v1${path}`, {
    ...options,
    headers: {
      "Authorization": `Bearer ${process.env.NUEFORM_API_KEY}`,
      "Content-Type": "application/json",
      ...options.headers,
    },
  });

  const body = await response.json();

  if (!response.ok) {
    const { code, message, status } = body.error;
    throw new NueFormApiError(code, message, status);
  }

  return body;
}

// Uso
async function getForm(formId) {
  try {
    const { data } = await nueformRequest(`/forms/${formId}`);
    return data;
  } catch (error) {
    if (error instanceof NueFormApiError) {
      switch (error.code) {
        case "NOT_FOUND":
          console.error(`Form ${formId} does not exist.`);
          return null;
        case "UNAUTHORIZED":
          console.error("Check your API key configuration.");
          break;
        case "RATE_LIMITED":
          console.warn("Rate limited. Implement backoff and retry.");
          break;
        default:
          console.error(`API error [${error.code}]: ${error.message}`);
      }
    }
    throw error;
  }
}

Python

python
import os
import requests

class NueFormApiError(Exception):
    def __init__(self, code, message, status):
        super().__init__(message)
        self.code = code
        self.status = status

class NueFormClient:
    def __init__(self, api_key=None):
        self.api_key = api_key or os.environ["NUEFORM_API_KEY"]
        self.base_url = "https://app.nueform.com/api/v1"

    def request(self, method, path, **kwargs):
        url = f"{self.base_url}{path}"
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json",
        }

        response = requests.request(method, url, headers=headers, **kwargs)
        body = response.json()

        if not response.ok:
            error = body["error"]
            raise NueFormApiError(
                error["code"], error["message"], error["status"]
            )

        return body

# Uso
client = NueFormClient()

try:
    result = client.request("GET", f"/forms/{form_id}")
    form = result["data"]
    print(f"Form: {form['title']}")

except NueFormApiError as e:
    if e.code == "NOT_FOUND":
        print(f"Form {form_id} does not exist.")
    elif e.code == "UNAUTHORIZED":
        print("Check your API key configuration.")
    elif e.code == "RATE_LIMITED":
        print("Rate limited. Implement backoff and retry.")
    else:
        print(f"API error [{e.code}]: {e}")

Mejores prácticas

Siempre verifica el campo error

Nunca asumas que una respuesta es exitosa basándote únicamente en la presencia de un cuerpo. Siempre verifica el campo error o comprueba el código de estado HTTP antes de procesar la respuesta.

Usa códigos de error específicos para el flujo de control

Compara con error.code (por ejemplo, NOT_FOUND, RATE_LIMITED) en lugar del código de estado HTTP. Los códigos de error son estables, descriptivos y más fáciles de razonar en la lógica de la aplicación.

Registra los detalles del error

Incluye la respuesta de error completa en tus registros para depuración. El code, message y status juntos proporcionan suficiente contexto para diagnosticar la mayoría de los problemas sin reproducir la solicitud.

Maneja errores 5xx con reintentos

Los errores del servidor (500 Internal Error) son típicamente transitorios. Implementa lógica de reintento con retroceso exponencial para estas respuestas. Limita los reintentos a 2--3 intentos antes de fallar.

No expongas mensajes de error a los usuarios finales

Los mensajes de error de la API están diseñados para desarrolladores, no para usuarios finales. Mapea los errores de la API a mensajes amigables para el usuario en tu aplicación.

Si recibes respuestas 500 Internal Error persistentes, contacta con soporte proporcionando los detalles de la solicitud y las marcas de tiempo. Los errores del servidor se registran en nuestro sistema y se investigan.

Ultima actualizacion: 6 de abril de 2026