20

In Joomla core I find still many calls like this:

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

But JError is deprecated since Platform release 12.1. So how should I use standard PHP exceptions.

1
  • 1
    The difference is moving from JError to PHP Errors isn't simply a one click process unfortunately. So if you're sure you're going to get an exception then do a try/catch statement as in the answer below. If you're sure you're going to get a JError then you need to do similar code to the above :) Commented Apr 24, 2014 at 19:53

3 Answers 3

20

As @DmitryRekun said, a good discussion is here. The key piece to consider in all of this is what type of error do you have?

There are two types of errors:

  1. Recoverable
  2. Unrecoverable.

The difference I tend to sum up as follows:

Can I still show the page that was requested, even though this error occurred?
  • Yes? - Recoverable
  • No? - Unrecoverable

Now that we know what we are dealing with. What should you do?

If the error is unrecoverable, you want to redirect them to an error page instead of continuing on to the requested page. That is as simple as the following:

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

Exception is a class that takes two parameters, a message and a code. It is recommended to try to use the HTTP Response Codes if they fit your scenario.

If the error is recoverable, you likely just want to display a message back to the end user while still showing them the page that they requested. This typically means that you should 'enqueue' a message for the application:

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

enqueueMessage takes two parameters, the error message and a message type. More info here (at the bottom).


There is also a third situation that occurs fairly often for me at least. Joomla will throw exceptions for different errors (such as a database query error). This means that Joomla thinks that this error is unrecoverable. However, you may want to continue on anyway. (For example, if I'm altering a table on update of my extension, I can just run the ALTER query, which will throw an exception if the table has previously been altered.)

In that case, you want to wrap the code that might throw an exception in a try...catch section:

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
}

Note that what you are doing is "catching" the unrecoverable error and forcing the system to recover and continue showing the requested page.


Add all this up and your case should be an unrecoverable error. (I know this because you have 'return false' afterwards, so you likely don't plan to continue and are giving up on the function.)

Thus I would rewrite this as follows:

// 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.
}
2
  • 1
    Good answer! But I would not rely on $this->get('Errors') because it is also deprecated. Commented Apr 25, 2014 at 6:04
  • Any comments on failed assertions, that is, internal errors? I'd like the program to die immediately at a failed assertion - is there a Joomla-specific way to do this? At the moment I register an assert handler if JDEBUG is true. Commented Oct 9, 2015 at 14:25
13

Here is how I'm managing an errors.

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

So if I get a 404 code from my Model (for example):

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

Then I catch it in the view or controller and throw one more Exception that Joomla will handle and will display 404 page. For any other I just show some generic error message to the user.

Also read this interesting discussion about errors handling.

4

Most code blocks like this can simply be replaced with enqueueMessage since they are not actually acting on the error and simply using JError to print them out.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.