Errores

Dogma proporciona soporte para errores o excepciones, donde un error o excepción (exception) representa un evento anómalo que requiere procesamiento especial. Para ello, proporciona las funciones throw() y peval() y la sentencia do.

Propagación de error

Mediante la propagación de error (error throwing o error raising) se genera un error. Se debe utilizar la función throw():

throw(error)
throw(format:text, ...args:text)

Ejemplos:

throw("esto es el mensaje de error.")
throw("InternalError: %s.", "Esto es el mensaje")  #con formateo del mensaje mediante fmt() implícito

Captura de errores

Cuando deseamos capturar un posible error, en un fragmento de código que sabemos genera errores, se utiliza la sentencia do, similar al try de otros lenguajes:

do [variables]
  Bloque
catch
  Bloque
finally
  Bloque

do [variables]
  Bloque
catch Nombre
  Bloque
finally
  Bloque

El bloque del do contiene el código a supervisar. La cláusula catch el código que debe ejecutarse para controlar el error. Si se desea acceso al objeto error, se puede indicar a continuación el nombre de la variable a crear y en la que depositarlo. Finalmente, la cláusula finally se utiliza para especificar un bloque de código que se ejecutará al finalizar el do, tanto si propaga error o no lo hace. Es ideal para asegurar código que deseamos que siempre se ejecute como, por ejemplo, el cierre de un archivo o socket.

Las cláusulas catch y finally son opcionales.

Como esta estructura es muy común, se ha extendido a otras (while, with, for, fn, proc y type) para hacer el código más limpio y elegante. Ejemplo:

while Expresión do
  #bloque
catch e
  #bloque
finally
  #bloque

Lo anterior es lo mismo que:

while Expresión do
  do
    #bloque
  catch e
    #bloque
  finally
    #bloque

Cuando la cláusula do se define junto con variables definidas con := y ::=, serán accesibles en las cláusulas catch y finally. Así pues, el siguiente código:

var cxn

do
  cxn = pool.acquire()
  ...
finally
  if cxn then cxn.release()

es similar a:

do cxn := pool.acquire()
  ...
finally
  if cxn then cxn.release()

Siempre hay que indicar el valor de las variables. Si no desea asignárselo inicialmente, asigne nil. Por otra parte, si desea indicar varias variables, separe pr coma (,).

Función reservada peval()

En Dogma, una función reservada (reserved function) es un tipo especial de función. Que se invoca como cualquier otra función, pero lleva aparejada un comportamiento especial que pueden no tener las funciones normales. Algunas funciones reservadas son await(), expect(), pawait() y peval().

La función reservada peval() (protected eval, evaluación protegida) evalúa/ejecuta una expresión y devuelve una lista con dos elementos:

Su sintaxis es como sigue:

peval(expresión)

Ejemplo:

if const [ok, res] = peval(sum(1, 2, 3)); ok then
  print("El resultado de la suma es: %s.", res)
else
  printf("Se ha producido el siguiente error: %s.", res)

Observe que peval() espera la expresión a monitorizar y devuelve cómo finalizó y su resultado o error capturado.

Función reservada catch()

La función reservada catch() ejecuta la expresión adjunta. Si ésta propaga error, lo captura y devuelve nil. En otro caso, devuelve el valor de la expresión.

Signatura:

catch(exp)

Anotación @catch

Cuando una función o procedimiento se anota con @catch, el compilador añade el código necesario para capturar cualquier error. De tal manera que si la función propaga un error, este código lo interceptará y la función devolverá nil. En otro caso, se devolverá el valor devuelto por la propia función.

Operadores && y ||

El operador && tiene como objeto ejecutar una expresión y, si no propaga ningún error, ejecutar la siguiente. Por su parte, el operador || tiene como objeto ejecutar una expresión y, si propaga error, ejecutar la siguiente.