it-swarm-eu.dev

Qual è il modo corretto di gestire le eccezioni?

Nel core di Joomla trovo ancora molte chiamate come questa:

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

Ma JError è obsoleto dalla versione 12.1 della piattaforma. Quindi, come dovrei usare le eccezioni standard PHP.

20
Harald Leithner

Come ha detto @DmitryRekun, una buona discussione è qui . Il pezzo chiave da considerare in tutto questo è che tipo di errore hai?

Esistono due tipi di errori:

  1. Recuperabile
  2. Non recuperabile.

La differenza che tendo a riassumere come segue:

Can I still show the page that was requested, even though this error occurred?
  • Sì? - Recuperabile
  • No? - Non recuperabile

Ora che sappiamo con cosa abbiamo a che fare. Cosa dovresti fare

Se l'errore è irrecuperabile, si desidera reindirizzarli a una pagina di errore invece di continuare sulla pagina richiesta . Questo è semplice come il seguente:

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

Exception è una classe che accetta due parametri, un messaggio e un codice. Si consiglia di provare a utilizzare codici di risposta HTTP se si adattano al proprio scenario.

Se l'errore è ripristinabile, è probabile che tu voglia solo visualizzare un messaggio all'utente finale, mostrando comunque la pagina richiesta. Ciò significa in genere che è necessario "accodare" un messaggio per l'applicazione:

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

enqueueMessage accetta due parametri, il messaggio di errore e un tipo di messaggio. Maggiori informazioni qui (in fondo).


C'è anche una terza situazione che si verifica abbastanza spesso per me almeno. Joomla genererà eccezioni per diversi errori (come un errore di query del database). Ciò significa che Joomla pensa che questo errore sia irrecuperabile. Tuttavia, potresti voler continuare comunque. (Ad esempio, se sto modificando una tabella durante l'aggiornamento della mia estensione, posso semplicemente eseguire la query ALTER, che genererà un'eccezione se la tabella è stata precedentemente modificata.)

In tal caso, si desidera racchiudere il codice che potrebbe generare un'eccezione in una sezione 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
}

Si noti che ciò che si sta facendo è "rilevare" l'errore irrecuperabile e forzare il sistema a ripristinare e continuare a mostrare la pagina richiesta.


Aggiungi tutto questo e il tuo caso dovrebbe essere un errore irrecuperabile. (Lo so perché hai "return false" in seguito, quindi probabilmente non hai intenzione di continuare e stai rinunciando alla funzione.)

Quindi riscriverei questo come segue:

// 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

Ecco come sto gestendo un errore.

Visualizza o Controller

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');
}

Quindi se ottengo un codice 404 dal mio modello (ad esempio):

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

Poi lo vedo nella vista o nel controller e lancio un'altra eccezione che Joomla gestirà e visualizzerà 404 pagine. Per qualsiasi altro mostro solo un messaggio di errore generico all'utente.

Inoltre leggi questa interessante discussione sulla gestione degli errori.

12
Dmitry Rekun

La maggior parte dei blocchi di codice come questo può essere semplicemente sostituita con enqueueMessage poiché in realtà non agiscono sull'errore e semplicemente utilizzano JError per stamparli.

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