Errores
Todos los códigos de error del contrato de entrega con su estado, su significado y la reacción correcta, incluida la ausencia de salida que nunca inicia una compilación y las respuestas de nivel de servicio.
- Disponibilidad: Experimental
- Evidencia: Leído del código fuente
- Referencia
Un solo sobre
Todo fallo tiene un código estable y un estado HTTP, y viaja como el mismo cuerpo JSON sea cual sea el servicio que lo produce:
{
"error": {
"code": "MODULE_NOT_FOUND",
"message": "…",
"diagnostics": [{ "code": "…", "message": "…" }]
}
}diagnostics está presente solo cuando hay alguno, lo que hoy significa una compilación fallida. Decide según code. El message es texto técnico en inglés para diagnosticar problemas y puede cambiar.
Una página de otro origen puede leer el error de una solicitud pública, como cualquier respuesta pública: lleva Access-Control-Allow-Origin: *, así que un navegador que no pudo cargar un módulo deja que la página lea el código y el mensaje. Los errores nunca se almacenan (no-store).
// Every failure is the same JSON envelope on every service. Branch on `code`,
// never on the message.
const origin = process.env.CDN_ORIGIN ?? process.env.DEV_ORIGIN;
// The options of the contract default to published delivery, so a development service refuses them with
// OPTION_UNSUPPORTED before it looks at the identity. A development consumer always asks for its output.
const development = !process.env.CDN_ORIGIN;
const options = development ? 'target=node&format=esm&env=development&min=false&sourcemap=inline' : 'target=browser&format=esm';
// A well-formed identity that no service holds
const request = `/m/@example/does-not-exist@0.0.1/modules/main?${options}`;
const response = await fetch(new URL(request, origin));
const type = response.headers.get('content-type') ?? '';
if (response.ok || !type.includes('application/json')) {
console.log(`unexpected answer: ${response.status} ${type}`);
process.exit(1);
}
const { error } = await response.json();
console.log(`${response.status} ${error.code}`);
console.log(error.message);
for (const diagnostic of error.diagnostics ?? []) console.log(` ${diagnostic.code}: ${diagnostic.message}`);
if (error.code !== 'PACKAGE_NOT_FOUND') process.exitCode = 1;Códigos
| Estado | Código | Significado | Qué hacer |
|---|---|---|---|
400 |
IDENTITY_INVALID |
La ruta no sigue la gramática: una versión que no es exacta, una barra codificada, un segmento de punto, una ruta de recurso incorrecta | Corrige la URL. Construye las rutas con el códec compartido. |
400 |
OPTION_INVALID |
Una opción es desconocida, está repetida, falta siendo obligatoria o tiene un valor fuera de su lista. Una solicitud de recurso estático con cualquier consulta. | Corrige la consulta. Consulta Opciones de la solicitud. |
400 |
OPTION_UNSUPPORTED |
La solicitud es válida y este servicio no puede producir esa salida en absoluto | Solicita una salida que el servicio produzca |
401 |
ACCESS_REQUIRED |
El recurso no es público y la solicitud no lleva contexto de acceso | Consulta Acceso privado |
403 |
ACCESS_DENIED |
El contexto de acceso no permite el recurso | Obtén un permiso válido o consulta a un administrador de la aplicación |
404 |
PACKAGE_NOT_FOUND |
Aquí no se ha preparado nada de este paquete. No dice nada sobre el paquete en su registro. | Revisa el nombre y el prefijo del registro, o prepara un release que lo use |
404 |
VERSION_MISMATCH |
Aquí se preparó otra versión del paquete, no esta | Solicita la versión que se sirve, o prepara un release con esta |
404 |
MODULE_NOT_FOUND |
Esta versión del paquete está disponible aquí y no publica ningún módulo con esta subruta | Revisa la subruta. Los archivos internos no son módulos públicos. |
404 |
OUTPUT_NOT_AVAILABLE |
La identidad es conocida y el servicio no tiene la salida solicitada: un conjunto de opciones que no se preparó, un módulo sin el recurso complementario pedido o un recurso que el paquete no declara | Prepara un release que la incluya. Reintentar no cambia nada. |
422 |
BUILD_FAILED |
Solo en desarrollo. El módulo existe y sus fuentes actuales no producen un artefacto válido. Se incluyen los diagnósticos del compilador y no se sirve en su lugar ninguna salida anterior. | Corrige las fuentes |
501 |
SOURCE_UNSUPPORTED |
El servicio no entrega esta fuente de módulos. Un servidor de desarrollo lo responde para /m/git/…, /m/digest/… y para un paquete instalado desde Git o desde un archivo comprimido. |
Carga ese paquete desde un origen que entregue su fuente, como un release del CDN que lo fijó |
404 |
NOT_FOUND |
Nivel de servicio: la ruta no corresponde a nada que este servicio sirva, como otra ruta, un host sin aplicación, o /resolution.json en el origen de entrega compartido |
Revisa el origen base y la ruta |
503 |
UNAVAILABLE |
Nivel de servicio: el servicio no puede responder ahora, por ejemplo porque su almacenamiento no responde | Reintenta más tarde. No dice nada sobre el recurso. |
500 |
INTERNAL |
Nivel de servicio: un fallo inesperado. Su mensaje no repite el del fallo. | Reintenta, e infórmalo si persiste |
Los tres últimos son la respuesta que da un servicio, en una ruta del contrato, a un fallo para el que el contrato no tiene código, de modo que un consumidor nunca se encuentra con el vocabulario de una implementación.
Una salida ausente no es una solicitud de compilación
Cada respuesta de este tipo describe lo que este CDN preparó y retuvo, y nada más. Ninguna afirma nada sobre el paquete en su registro, ni promete que volver a pedirlo compile algo, ni describe lo que preparó otro inquilino.
OUTPUT_NOT_AVAILABLE es la respuesta de un servicio que solo entrega. Significa que el servicio buscó, no encontró nada y no hizo nada más:
- no se inició, reanudó ni encoló ninguna compilación;
- la respuesta no es
OPTION_UNSUPPORTED, porque el servicio podría tener la salida; - la respuesta nunca es
immutable, porque la salida se puede preparar más adelante.
// A published service only retrieves. A valid request for an output that was
// not prepared is a 404 with OUTPUT_NOT_AVAILABLE, and asking again changes
// nothing: no GET starts a build.
const origin = process.env.CDN_ORIGIN;
// Set UNPREPARED_REQUEST to a valid option set that your release did not prepare
const request = process.env.UNPREPARED_REQUEST ?? '/m/@example/shared@1.0.0/modules/text?target=node&format=cjs';
for (const attempt of [1, 2]) {
const response = await fetch(new URL(request, origin));
const { error } = await response.json();
console.log(`attempt ${attempt}: ${response.status} ${error.code}`);
console.log(` Cache-Control: ${response.headers.get('cache-control')}`);
const acceptable = ['OUTPUT_NOT_AVAILABLE', 'OPTION_UNSUPPORTED'].includes(error.code);
if (!acceptable) process.exitCode = 1;
}En un servidor de desarrollo la misma situación se maneja de otra manera a propósito: un módulo conocido se compila desde sus fuentes actuales cuando se solicita, y BUILD_FAILED informa las fuentes que no compilan.
| Situación | Servidor de desarrollo | Entrega publicada |
|---|---|---|
| Módulo conocido, salida que no se tiene | Compila en el momento | 404 OUTPUT_NOT_AVAILABLE |
| Las fuentes no compilan | 422 BUILD_FAILED con diagnósticos |
No aplica: el fallo pertenece al trabajo de preparación, y el release activo no se toca |
| Opción válida que el servicio nunca produce | 400 OPTION_UNSUPPORTED |
400 OPTION_UNSUPPORTED |
Errores de selección de salida
Elegir mal la salida de un módulo público en el código fuente, por ejemplo importar un módulo que solo es una hoja de estilos sin .css, no es un error de entrega: se detecta cuando se compila o analiza el módulo que importa, y te llega como diagnóstico de esa compilación en un servidor de desarrollo, o como un trabajo de preparación fallido en el CDN. Los diagnósticos son OUTPUT_NOT_FOUND, OUTPUT_AMBIGUOUS y STYLE_BINDING_UNSUPPORTED; consulta Seleccionar una salida.
En código
import { ContractError } from '@beyond-js/artifact-api';
const response = await fetch(url);
if (!response.ok) {
const error = ContractError.from(response.status, await response.json());
error.code; // 'OUTPUT_NOT_AVAILABLE'
error.status; // 404
error.diagnostics; // compiler diagnostics of a failed build, when present
}ContractError.from devuelve undefined cuando el cuerpo no es un sobre de error de este contrato, por ejemplo la página de error HTML de un proxy.