Comment corriger LIMIT_EXCEEDED dans les déploiements Salesforce

Les tests Apex d'un déploiement, ou le chargement de données qui les précède, ont atteint l'une des limites de gouverneur ou limites globales de Salesforce.

Se produit lors : de l'exécution des tests Apex ou d'opérations de données en masse, pas lors de la validation du déploiement de métadonnées elle-même

Ce que cela signifie

LIMIT_EXCEEDED regroupe une famille de limites Salesforce, le plus souvent des limites de gouverneur Apex comme les requêtes SOQL, les instructions DML ou le temps CPU, atteintes lors de l'exécution des tests qu'un déploiement requiert. Cela peut aussi signifier qu'une limite globale de l'organisation, comme les appels API quotidiens ou les destinataires d'e-mails en masse, a été dépassée par une automatisation que le déploiement déclenche.

Les limites de gouverneur par transaction (100 requêtes SOQL, 150 instructions DML, 10 000 millisecondes CPU en synchrone) se réinitialisent à chaque transaction, donc cela pointe presque toujours vers du code non optimisé en masse dans une seule transaction plutôt qu'un véritable plafond de capacité de l'organisation.

Diagnostic

Causes courantes

La configuration des données de test Apex fait trop en une seule transaction
Une méthode de test insère de grands volumes d'enregistrements ou déclenche une automatisation en cascade qui pousse l'utilisation de SOQL, DML ou CPU au-delà de la limite par transaction.
Le chargement de données en masse contourne la mise en lot (bulkification)
Une migration de données traite les enregistrements un par un, ou en petits lots, et déclenche un déclencheur qui n'a pas été écrit pour gérer efficacement des volumes en masse.
Limite quotidienne d'API ou d'e-mails déjà consommée
D'autres intégrations ou tâches planifiées dans l'organisation ont déjà utilisé la majeure partie d'une limite quotidienne partagée avant que les opérations propres au déploiement ne s'exécutent.

La solution

  1. Mettre en lot (bulkifier) le chemin de code qui atteint la limite
    Réécrivez le déclencheur, la classe ou le test pour opérer sur des collections plutôt que sur des enregistrements individuels, réduisant les appels SOQL et DML par transaction.
    // Bad: SOQL inside a loop
    for (Account a : accounts) {
        List<Contact> cons = [SELECT Id FROM Contact WHERE AccountId = :a.Id];
    }
    
    // Good: one query outside the loop
    Map<Id, List<Contact>> conMap = new Map<Id, List<Contact>>();
    for (Contact c : [SELECT Id, AccountId FROM Contact WHERE AccountId IN :accountIds]) {
        if (!conMap.containsKey(c.AccountId)) conMap.put(c.AccountId, new List<Contact>());
        conMap.get(c.AccountId).add(c);
    }
  2. Réduire le volume de données de test au minimum nécessaire
    Réduisez la configuration des tests Apex au plus petit jeu de données qui exerce encore la logique testée.
  3. Vérifier les limites de l'organisation avant les gros déploiements
    Examinez les limites d'API et autres limites quotidiennes dans Setup avant d'exécuter un chargement de données en masse ou un déploiement qui s'ajoute à l'utilisation déjà consommée ce jour-là.
En pratique

Comment Serpent évite cela

Serpent réserve des scratch orgs préchauffés pour les exécutions de tests, de sorte qu'un test en masse ou un chargement de données rencontre un ensemble de limites propre au lieu de rivaliser avec tout ce qui tourne déjà dans un sandbox partagé. Consultez la bibliothèque des erreurs de déploiement Salesforce.

Tableau de bord des releases avec alertes de conflit dans Serpent

Prévention

Écrire chaque déclencheur en toute sécurité pour le traitement en masse dès la première ligne, pas après coup
Interrogez et effectuez du DML sur des collections par défaut dans les nouveaux déclencheurs, afin que la sécurité en masse soit la conception de départ, pas un correctif appliqué après le premier échec LIMIT_EXCEEDED.
Effectuer des tests de charge avec des tailles de lots réalistes avant la production
Exécutez les scripts de migration et de chargement en masse sur des volumes de données à l'échelle de la production dans un scratch org ou un sandbox avant de planifier le chargement réel.
Surveiller les limites globales de l'organisation, pas seulement celles par transaction
Suivez l'utilisation quotidienne des appels API et des e-mails en masse dans le temps, afin que les opérations propres au déploiement ne soient pas celles qui font finalement basculer une limite partagée.
Questions fréquentes

LIMIT_EXCEEDED, expliqué

LIMIT_EXCEEDED est-il identique à une exception de limite de gouverneur dans Apex ?
Ils sont étroitement liés. Les limites de gouverneur lèvent une System.LimitException dans Apex, qui apparaît comme un échec de test ; LIMIT_EXCEEDED est l'erreur API plus large pour le dépassement de limites globales de l'organisation comme les appels API ou les destinataires d'e-mails en masse.
Les limites de gouverneur se réinitialisent-elles entre Test.startTest() et Test.stopTest() ?
Oui. Test.startTest() donne au code qui suit un nouvel ensemble de limites de gouverneur, distinct de ce que la configuration propre du test a consommé, c'est pourquoi il est important de déplacer la configuration lourde avant cet appel.
Les limites de gouverneur sont-elles les mêmes dans toutes les éditions Salesforce ?
La plupart des limites Apex par transaction sont identiques dans toutes les éditions, mais certaines limites globales de l'organisation, comme les appels API par jour, varient selon l'édition et le nombre de licences utilisateur, si bien que deux organisations peuvent atteindre REQUEST_LIMIT_EXCEEDED à des volumes très différents.

Démarrez gratuitement. Sans carte bancaire, sans installation, sans engagement.

Configuration en moins de 15 minutes. Aucun recrutement DevOps nécessaire.

Curieux de livrer plus vite avant de vous lancer ? Parlons-en

Sans engagement.