Apex Academy
Módulo 8·02·30 min

Tipos de excepción en Apex

No todos los fallos son iguales: no es lo mismo que una cuenta no exista que un guardado rechazado. Cada tipo de excepción dice qué pasó, y cada catch se ocupa del suyo.

En Admin esLos códigos de error de un error.csv de Data Loader

✓ En esta sub-lección

  1. 01Reconocer las excepciones más habituales y qué situación provoca cada una.
  2. 02Encadenar varios catch, del tipo más concreto al más general.
  3. 03Explicar por qué LimitException no se puede capturar.

La nutria: ¿Te acuerdas? · Repaso de la lección 1

Quieres que un importe mal escrito no pare el resto de filas. ¿Dónde va el try?

En la tarea 1 el fallo era siempre el mismo: un texto que no era un número. Pero en el puente con el ERP pueden fallar cosas muy distintas, y no todas se tratan igual. Si la cuenta no existe, hay que avisar al ERP de que el código es incorrecto. Si Salesforce rechaza el guardado, hay que decir por qué. El tipo de la excepción es lo que te permite distinguirlas.

Las excepciones que más te vas a encontrar

ExcepciónCuándo saltaEjemplo
DmlExceptionUn insert, update o delete rechazado: una regla de validación, un campo obligatorio, un propietario inactivo.insert opp; con un OwnerId de un usuario inactivo
QueryExceptionAsignas a un solo registro una consulta que no devuelve ninguno (o que devuelve más de uno).Account a = [SELECT … WHERE ERP_Code__c = 'ERP-404'];
NullPointerExceptionUsas algo que es null como si tuviera valor.acc.Name cuando acc es null
TypeExceptionUna conversión imposible entre tipos.Decimal.valueOf('12.500,00')
ListExceptionPides una posición que la lista no tiene.rows[5] en una lista de 3
SObjectExceptionLees un campo que no pediste en la consulta.a.Industry si el SELECT solo traía Id
LimitExceptionSuperas un governor limit. No se puede capturar.La consulta número 101

La nutria: Los códigos de error que ya has visto

Seguro que en un error.csv de Data Loader has visto REQUIRED_FIELD_MISSING, FIELD_CUSTOM_VALIDATION_EXCEPTION o INACTIVE_OWNER_OR_USER; yo me los sé de memoria. Son los códigos de estado de un guardado rechazado, y en Apex llegan dentro de una DmlException: e.getDmlMessage(0) te da el mensaje del primer registro que falló, y e.getDmlType(0), su código.

Varios catch, del más concreto al más general

Un try puede llevar varios catch seguidos. Cuando salta una excepción, Apex los prueba de arriba abajo y usa el primero cuyo tipo encaja. Todas las excepciones son hijas de Exception, así que un catch (Exception e) encaja con cualquiera: si lo pones, que sea el último, como red de seguridad para lo que no esperabas. Si lo pusieras el primero, se quedaría con todo y los catch concretos no llegarían a usarse nunca.

Apex
try {
    Account acc = [SELECT Id, OwnerId FROM Account WHERE ERP_Code__c = :erpCode LIMIT 1];
    insert new Opportunity(Name = erpCode, AccountId = acc.Id, OwnerId = acc.OwnerId,
                           StageName = 'Prospecting', CloseDate = Date.today());
} catch (QueryException e) {
    System.debug('Código de cuenta desconocido: ' + erpCode);      // avisar al ERP
} catch (DmlException e) {
    System.debug(e.getDmlType(0) + ': ' + e.getDmlMessage(0));    // el motivo exacto
} catch (Exception e) {
    System.debug('Inesperado: ' + e.getTypeName() + ' en la línea ' + e.getLineNumber());
}
getTypeName() dice qué tipo de excepción era (por ejemplo, System.ListException) y getLineNumber() en qué línea saltó: oro puro cuando cae en la red de seguridad.

¿QUÉ EXCEPCIÓN SALTA? ·aciertos 0/0

Account a = [SELECT Id FROM Account WHERE ERP_Code__c = 'ERP-404'];

Paso 1 de 7

Elige la excepción que lanza esta línea.

Para cada línea, ¿qué excepción salta? Fíjate en la pista de cada una.

La nutria: ¿Y por qué no un Flow? Porque el fault path solo recibe un texto

Esto nos pasó con la primera versión: en Flow, cuando un elemento falla, el fault path recibe un único texto, $Flow.FaultMessage. Queríamos tratar distinto «la cuenta no existe» y «el guardado fue rechazado», y la única forma era buscar palabras dentro de ese texto con una fórmula… y cruzar los dedos para que Salesforce no cambiara la redacción del mensaje. En Apex el tipo de la excepción ya te dice qué pasó, y cada catch se ocupa del suyo.