Errores, límites y control de versiones

Errores

Un comando que falla se rechaza con un EmbedError. Su code es estable y está pensado para basar decisiones en él; message está escrito para un desarrollador que lee una consola.

const { EmbedError } = IconMapEmbed;

try {
  await map.applyBookmark({ bookmarkId });
} catch (e) {
  if (!(e instanceof EmbedError)) throw e;
  switch (e.code) {
    case "unknown_id":        return forgetBookmark(bookmarkId);
    case "denied_capability": return hideBookmarkMenu();
    default:                  report(e.code, e.message, e.requestId);
  }
}
Propiedad
code Uno de los códigos de error
message Qué ha fallado, en una frase
detailedMessage La causa subyacente, cuando la hay
requestId Presente cuando el fallo implicó a nuestros servidores; indíquelo en una solicitud de soporte
detail Información estructurada adicional, por ejemplo { undeclared: [...] } en undeclared_filter

Qué significa cada código

Los códigos se agrupan en cuatro familias, y la respuesta adecuada es distinta para cada una.

Su página no tiene permiso: denied_origin, denied_capability. Los decide el autor. denied_origin rechaza el propio ready: no se abrió ninguna sesión y nada funcionará hasta que su sitio se añada a los orígenes permitidos del mapa. denied_capability significa que un grupo está desactivado (o, para exportImage y print, que una etiqueta de confidencialidad impide la exportación). Oculte la función; reintentar no sirve de nada.

El mapa no lo tiene: unsupported_command, unknown_id, undeclared_filter. Compruebe capabilities.commands antes de ofrecer una función, y cree los selectores a partir de lo que informa el mapa (getLayers, getBookmarks, getFilterSchema) en lugar de usar ids escritos en su código.

La llamada era incorrecta: invalid_args, too_large. Un error en el código que llama; el mensaje indica el argumento.

Vuelva a intentarlo más tarde: rate_limited, busy, budget_exceeded, data_error, timeout, not_ready. Espere antes de reintentar en lugar de repetir en bucle.

Dos códigos proceden del SDK y no del mapa: timeout (sin respuesta en 15 segundos; se cambia con la opción commandTimeoutMs) y destroyed (destruyó o recargó el mapa mientras un comando estaba en curso).

Errores de inicio

Si el mapa no puede iniciarse en absoluto (una publicación revocada, un token rechazado), ready se rechaza y se llama a la opción onError. El mapa muestra su propio mensaje al lector, a menos que pase hideErrors: true y muestre el suyo.

Límites

Son fijos. Su página no puede aumentarlos y un autor no puede reducirlos; también se exportan como EMBED_LIMITS.

Límite Valor Si se supera
Comandos 60 por segundo rate_limited
Un mensaje de comando 64 KB too_large, y el comando no se llega a leer
Una carga de evento 32 KB el evento se descarta
Claves en highlight / selectByKey 500 invalid_args
Operaciones de análisis 60 por minuto, 1 en ejecución + 4 en espera por capa budget_exceeded, busy
Resultados de análisis 1000 ids o 200 filas por lista se recortan, con truncated: true
featureHover uno cada 100 ms se agrupan: el último valor siempre llega

Capacidades, no versiones

await map.ready se resuelve con un descriptor de lo que este mapa atenderá:

{
  protocol: 2,
  commands: ["getView", "setView", ...],
  events:   ["viewChanged", "featureClick", ...],
  policy:   { enabled: true, read: true, camera: true, layers: true, ... },
  map:      { publishId, surface: "published", dataMode: "snapshot", bookmarks: true, locales: ["en-US", "de-DE", ...] }
}

commands ya es la intersección de tres cosas: lo que implementa esta versión del mapa, lo que admite este tipo de inserción y lo que activó el autor. Por eso, la única comprobación que necesita es:

if (capabilities.commands.includes("exportImage")) showExportButton();

Los comandos nuevos llegan añadiéndose a esa lista. Una página escrita hoy sigue funcionando; una página que quiera un comando más reciente lo solicita y se degrada correctamente cuando no está.

Compatibilidad entre versiones antiguas y nuevas

El mapa y el SDK se publican por separado, así que cada uno se adapta a que el otro sea más antiguo.

Su página usa El mapa es Qué ocurre
SDK actual Actual Todo lo que describe esta documentación
SDK actual Un mapa antiguo sin la API de control El mapa se muestra. ready se resuelve con una lista commands vacía en lugar de quedarse colgado; los comandos se rechazan con unsupported_command
SDK 0.x (solo visualización y setFilters) Actual Funciona sin cambios

La versión acordada está en map.protocol. No debería necesitarla.

Ciclo de vida

map.reload();      // reload the frame; subscriptions are restored when it is back
map.destroy();     // remove the frame; anything in flight rejects with `destroyed`

getEmbed(element) devuelve el identificador ya montado en un elemento, y reset(element) lo destruye; resulta útil en marcos de trabajo donde el código que monta el mapa no es el que hace la limpieza.

Modelo de seguridad

Para una revisión de seguridad, estas son las propiedades que importan:

  • Aislamiento. El mapa se ejecuta en un iframe de origen cruzado. No puede leer su página y su página no puede leerlo; el único canal es postMessage.
  • Quién puede hablar. El mapa solo acepta mensajes de la ventana que lo enmarcó, y solo si el origen de esa ventana está entre los orígenes permitidos del autor. Un marco de terceros en su página no puede controlar el mapa, ni siquiera desde un origen permitido. A su vez, el SDK solo acepta mensajes del marco que creó, en el origen que espera, y no envía tokens a ningún otro sitio.
  • Qué se puede decir. Una lista cerrada de comandos con argumentos validados. Ninguno acepta una URL, una consulta, un estilo, HTML ni script.
  • Qué vuelve. Solo lo que un lector ya puede ver: campos de información sobre herramientas, nunca filas completas; nunca la configuración, los orígenes de datos ni las consultas del mapa.
  • Quién decide. Los orígenes permitidos y los conmutadores de los grupos de comandos forman parte de la publicación firmada y se aplican dentro del mapa; y, cuando un comando llega a nuestros servidores (refreshData), también se aplican allí.
  • El acceso a los datos no cambia. La API no añade ninguna vía nueva a los datos. Un mapa publicado lee lo que congeló la publicación o lo que permite la seguridad de nivel de fila de su token; una inserción organizativa lee como el espectador que ha iniciado sesión.
  • Etiquetas de confidencialidad. La exportación de imágenes y la impresión se rigen por las mismas reglas de etiquetas de confidencialidad que cualquier otra exportación de Icon Map.
  • Telemetría. Contamos las sesiones de control y qué grupos de comandos se usan. Los valores de los argumentos (valores de filtro, selecciones, los títulos de sus menús) nunca se recopilan.

La misma lista de orígenes permitidos establece también la directiva frame-ancestors, por lo que determina qué sitios pueden enmarcar el mapa.