Erreurs, limites et gestion des versions

Erreurs

Une commande qui échoue est rejetée avec une EmbedError. Son code est stable et conçu pour servir de critère de branchement ; message est rédigé pour un développeur qui lit la console.

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);
  }
}
Propriété
code L'un des codes d'erreur
message Ce qui s'est mal passé, en une phrase
detailedMessage La cause sous-jacente, s'il y en a une
requestId Présent lorsque l'échec a impliqué nos serveurs : indiquez-le dans votre demande au support
detail Compléments structurés, par exemple { undeclared: [...] } sur undeclared_filter

Quel code signifie quoi

Les codes se répartissent en quatre familles, et la bonne réaction diffère pour chacune.

Votre page n'est pas autorisée : denied_origin, denied_capability. C'est l'auteur qui en décide. denied_origin rejette ready lui-même : aucune session n'est ouverte, et rien ne fonctionnera tant que votre site n'aura pas été ajouté aux origines autorisées de la carte. denied_capability signifie qu'un groupe est désactivé (ou, pour exportImage et print, qu'une étiquette de confidentialité refuse l'exportation). Masquez la fonctionnalité ; réessayer ne servira à rien.

La carte ne la propose pas : unsupported_command, unknown_id, undeclared_filter. Vérifiez capabilities.commands avant de proposer une fonctionnalité, et construisez vos sélecteurs à partir de ce que la carte indique (getLayers, getBookmarks, getFilterSchema) plutôt qu'à partir d'id inscrits dans votre code.

L'appel était incorrect : invalid_args, too_large. Il s'agit d'un bogue dans le code appelant ; le message nomme l'argument.

Réessayez plus tard : rate_limited, busy, budget_exceeded, data_error, timeout, not_ready. Espacez les tentatives plutôt que de boucler.

Deux codes proviennent du SDK et non de la carte : timeout (aucune réponse en 15 secondes ; modifiable avec l'option commandTimeoutMs) et destroyed (vous avez détruit ou rechargé la carte pendant qu'une commande était en cours).

Échecs au démarrage

Si la carte ne peut pas démarrer du tout (publication révoquée, jeton refusé), ready est rejetée et l'option onError est appelée. La carte affiche son propre message au lecteur, sauf si vous passez hideErrors: true et affichez le vôtre.

Limites

Elles sont fixes. Votre page ne peut pas les relever et un auteur ne peut pas les abaisser ; elles sont aussi exportées sous le nom EMBED_LIMITS.

Limite Valeur En cas de dépassement
Commandes 60 par seconde rate_limited
Un message de commande 64 KB too_large, et la commande n'est jamais lue
Une charge utile d'événement 32 KB l'événement est abandonné
Clés dans highlight / selectByKey 500 invalid_args
Opérations d'analyse 60 par minute, 1 en cours + 4 en attente par couche budget_exceeded, busy
Résultats d'analyse 1 000 id ou 200 lignes par liste tronqués, avec truncated: true
featureHover un toutes les 100 ms regroupés : la dernière valeur arrive toujours

Des capacités, pas des versions

await map.ready se résout avec un descripteur de ce à quoi cette carte répondra :

{
  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 est déjà l'intersection de trois éléments : ce que cette version de la carte implémente, ce que ce type d'incorporation prend en charge et ce que l'auteur a activé. La seule vérification dont vous aurez jamais besoin est donc :

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

Les nouvelles commandes apparaissent en étant ajoutées à cette liste. Une page écrite aujourd'hui continue de fonctionner ; une page qui veut une commande plus récente la demande et fonctionne en mode dégradé lorsqu'elle est absente.

Compatibilité entre anciennes et nouvelles versions

La carte et le SDK sont publiés séparément : chacun s'accommode de ce que l'autre soit plus ancien.

Votre page utilise La carte est Résultat
Le SDK actuel Actuelle Tout ce que décrit cette documentation
Le SDK actuel Une carte plus ancienne sans API de contrôle La carte s'affiche. ready se résout avec une liste commands vide au lieu de rester bloquée ; les commandes sont rejetées avec unsupported_command
SDK 0.x (affichage et setFilters uniquement) Actuelle Fonctionne sans modification

La version convenue se trouve dans map.protocol. Vous ne devriez pas en avoir besoin.

Cycle de vie

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) renvoie le handle déjà monté dans un élément, et reset(element) le détruit : utile dans les frameworks où le code qui monte la carte n'est pas celui qui fait le nettoyage.

Modèle de sécurité

Pour une revue de sécurité, voici les propriétés qui comptent :

  • Isolation. La carte s'exécute dans un iframe d'origine différente. Elle ne peut pas lire votre page, et votre page ne peut pas la lire ; le seul canal est postMessage.
  • Qui peut parler. La carte n'accepte de messages que de la fenêtre qui l'a encadrée, et seulement si l'origine de cette fenêtre figure parmi les origines autorisées par l'auteur. Un cadre tiers sur votre page ne peut pas piloter la carte, même depuis une origine autorisée. Le SDK, de son côté, n'accepte de messages que du cadre qu'il a créé, sur l'origine attendue, et n'envoie les jetons nulle part ailleurs.
  • Ce qui peut être dit. Une liste fermée de commandes aux arguments validés. Aucune n'accepte d'URL, de requête, de style, de HTML ou de script.
  • Ce qui revient. Uniquement ce qu'un lecteur voit déjà : les champs d'info-bulle, jamais de lignes complètes ; jamais la configuration de la carte, ses sources de données ou ses requêtes.
  • Qui décide. Les origines autorisées et les réglages des groupes de commandes font partie de la publication signée, appliquée à l'intérieur de la carte et, lorsqu'une commande atteint nos serveurs (refreshData), appliquée là aussi.
  • L'accès aux données est inchangé. L'API n'ajoute aucun nouveau chemin vers les données. Une carte publiée lit ce que la publication a figé ou ce que la sécurité au niveau des lignes de son jeton autorise ; une incorporation organisationnelle lit les données au nom du lecteur connecté.
  • Étiquettes de confidentialité. L'export d'image et l'impression obéissent aux mêmes règles d'étiquettes de confidentialité que toute autre exportation depuis Icon Map.
  • Télémétrie. Nous comptons les sessions de contrôle et les groupes de commandes utilisés. Les valeurs des arguments (valeurs de filtre, sélections, titres de vos menus) ne sont jamais collectées.

La même liste d'origines autorisées définit aussi la stratégie frame-ancestors : elle détermine donc quels sites peuvent encadrer la carte.