DMarlon Studio

Lección 7 · 7 de 20

Excepciones · Pascal

Lance y capture excepciones en Object Pascal con raise y try/except, y cree sus propias clases de excepción para los errores de su aplicación.

Pascal · Excepciones en DMarlon Studio: el código del ejemplo y su salida en la terminal

Una excepción es un objeto que interrumpe el flujo normal cuando algo va mal. Todas descienden de Exception (unidad SysUtils), y crear la suya es una línea: EOutOfStock = class(Exception). Por convención, sus nombres empiezan por E.

Order comprueba el pedido y, si no puede atenderlo, lo dice con `raise`: raise EOutOfStock.CreateFmt(...) crea la excepción con un mensaje al estilo de Format y la lanza. La función se detiene ahí mismo y la ejecución salta al manejador más cercano. StrToInt('ten') también lanza la suya, EConvertError, sin que usted escriba nada.

El bloque `try ... except` captura lo que se lance dentro. Cada `on E: Clase do` atiende un tipo y da acceso al objeto en E, con su Message y su ClassName. Se prueban en orden, así que los específicos van antes y Exception, que lo atrapa todo, al final: por eso el EArgumentException del pedido de 0 cae en la última línea.

Como el try está dentro del bucle, un pedido erróneo no detiene a los demás: se procesan los cuatro y el programa termina con All requests handled. El objeto de la excepción lo libera el propio except; usted no tiene que hacer Free.

Código · main.pas

program main;uses SysUtils;type  EOutOfStock = class(Exception);  // our own exception classconst  Stock = 5;  Requests: array[0..3] of String = ('3', 'ten', '0', '8');procedure Order(const qtyText: String);var qty: Integer;begin  qty := StrToInt(qtyText);  // raises EConvertError if it is not a number  if qty <= 0 then    raise EArgumentException.Create('quantity must be positive');  if qty > Stock then    raise EOutOfStock.CreateFmt('only %d left, %d requested', [Stock, qty]);  WriteLn('Order for ', qty, ' accepted');end;var request: String;begin  for request in Requests do    try      Order(request);    except      on E: EOutOfStock do WriteLn('Out of stock: ', E.Message);      on E: EConvertError do WriteLn('Not a number: ', E.Message);      on E: Exception do WriteLn(E.ClassName, ': ', E.Message);    end;  WriteLn('All requests handled');end.

Salida · fpc main.pas && ./main

Order for 3 accepted
Not a number: "ten" is an invalid integer
EArgumentException: quantity must be positive
Out of stock: only 5 left, 8 requested
All requests handled

Para recordar

  • raise lanza una excepción y corta la ejecución.
  • Sus excepciones heredan de Exception y empiezan por E.
  • on E: Clase do captura un tipo concreto.
  • Ponga los tipos específicos antes que Exception.
  • El objeto de la excepción se libera solo al capturarla.

Ejercicio

Cree EMaxOrder = class(Exception) y lánzela cuando la cantidad pase de 100; añada '250' a Requests y un manejador propio que escriba «Too many units».