it-swarm-es.tech

¿Cuál es la forma correcta para el manejo de excepciones?

En el núcleo de Joomla todavía encuentro muchas llamadas como esta:

    // Check for errors.
    if (count($errors = $this->get('Errors')))
    {
        JError::raiseError(500, implode("\n", $errors));
        return false;
    }

Pero JError está en desuso desde la versión de plataforma 12.1. Entonces, ¿cómo debo usar el estándar PHP excepciones.

20
Harald Leithner

Como dijo @DmitryRekun, una buena discusión es aquí . La pieza clave a considerar en todo esto es ¿qué tipo de error tiene?

Hay dos tipos de errores:

  1. Recuperable
  2. Irrecuperable.

La diferencia tiendo a resumir de la siguiente manera:

Can I still show the page that was requested, even though this error occurred?
  • ¿Sí? - recuperable
  • ¿No? - Irrecuperable

Ahora que sabemos a qué nos enfrentamos. Que deberias hacer

Si el error es irrecuperable, desea redirigirlos a una página de error en lugar de continuar a la página solicitada . Eso es tan simple como lo siguiente:

throw new Exception(JText::_('COM_MYCOMP_ERROR_MESSAGE_NOT_FOUND'), 404);

Exception es una clase que toma dos parámetros, un mensaje y un código. Se recomienda intentar usar Códigos de respuesta HTTP si se ajustan a su escenario.

Si el error es recuperable, es probable que solo desee mostrar un mensaje al usuario final sin dejar de mostrarle la página que solicitó. Esto generalmente significa que debe 'poner en cola' un mensaje para la aplicación:

JFactory::getApplication()->enqueueMessage($error, 'error');

enqueueMessage toma dos parámetros, el mensaje de error y un tipo de mensaje. Más información aquí (en la parte inferior).


También hay una tercera situación que ocurre con bastante frecuencia al menos para mí. Joomla lanzará excepciones para diferentes errores (como un error de consulta de la base de datos). Esto significa que Joomla piensa que este error es irrecuperable. Sin embargo, es posible que desee continuar de todos modos. (Por ejemplo, si estoy alterando una tabla en la actualización de mi extensión, simplemente puedo ejecutar la consulta ALTER, que arrojará una excepción si la tabla ha sido alterada previamente).

En ese caso, desea ajustar el código que podría generar una excepción en una sección try ... catch:

try {
    // exception generating code
    throw new Exception('Normally you would have other code that calls a class that throws the exception', 500);
} catch (Exception $e) {
    $msg = $e->getMessage(); // Returns "Normally you would have other code...
    $code = $e->getCode(); // Returns '500';
    JFactory::getApplication()->enqueueMessage($msg, 'error'); // commonly to still display that error
}

Tenga en cuenta que lo que está haciendo es "detectar" el error irrecuperable y obligar al sistema a recuperarse y continuar mostrando la página solicitada.


Agregue todo esto y su caso debería ser un error irrecuperable. (Lo sé porque después tienes 'return false', por lo que es probable que no planees continuar y renuncies a la función).

Por lo tanto, volvería a escribir esto de la siguiente manera:

// Check for errors.
if (count($errors = $this->get('Errors')))
{
    throw new Exception(implode("\n", $errors), 500);
    return false; // you can remove this too, technically since the exception will take you out of this function.
}
17
David Fritsch

Así es como estoy gestionando un error.

Ver o Controlador

try
{
    $this->item = $this->get('Item');
}
catch (Exception $e)
{
    if ($e->getCode() == 404)
    {
        // Not found
        throw new Exception($e->getMessage(), 404);
    }

    // Generic errors
    JFactory::getApplication()->enqueueMessage(JText::_('COM_MYCOMP_ERROR_OCCURRED'), 'error');
}

Entonces, si obtengo un código 404 de mi Modelo (por ejemplo):

if (empty($data))
{
    throw new Exception(JText::_('COM_MYCOMP_ERROR_MESSAGE_NOT_FOUND'), 404);
}

Luego lo capto en la vista o controlador y lanzo una Excepción más que Joomla manejará y mostrará la página 404. Para cualquier otro, solo muestro un mensaje de error genérico al usuario.

También leer esta interesante discusión sobre el manejo de errores.

12
Dmitry Rekun

La mayoría de los bloques de código como este simplemente se pueden reemplazar con enqueueMessage ya que en realidad no están actuando sobre el error y simplemente usan JError para imprimirlos.

// Check for errors.
if (count($errors = $this->get('Errors'))) {
    foreach($errors as $error) {
        JFactory::getApplication()->enqueueMessage($error, 'error');
    }
}
4
Spunkie