it-swarm-es.tech

Captura de excepción / error en la transacción de la base de datos

Estoy usando la siguiente forma en joomla 2.5 y 3 para ejecutar la consulta de la base de datos:

$database = JFactory::getDBO();
$database->setQuery
$database->execute();

pero, ¿cómo puedo detectar errores/excepciones si la consulta falla por algún motivo porque $database->getErrorNum() está en desuso?

11
dev-m

JError ha quedado en desuso en J3.x, a favor de PHP excepciones, ya que entremezclado 2 conceptos de programación diferentes : registro y manejo de errores (el lado de registro ahora ha sido implementado como JLog ).

Para su caso exacto, puede envolver su código en un bloque try/catch para obtener el error, como se muestra en esto SO respuesta :

try {
    ...
    $db->setQuery($query);
    $result = $db->loadResult();
}
catch (Exception $e){
    echo $e->getMessage();
}

Tenga en cuenta que $database->execute() se establece en NO funciona en J2.5 . Debe usar $database->query() si necesita un equivalente.

En Joomla 2.5 y 3.x, los métodos JDatabase objectupdateRecord() y insertRecord() también arrojan errores que puede detectar si fallan:

try {
    JFactory::getDbo()->updateObject('#_table_name', $data);
} catch (Exception $e) {
    //...handle the exception
}

Si está desarrollando solo para Joomla 3.x, también puede usar un bloque try try con transacciones SQL para obtener los detalles del error:

$db = JFactory::getDbo();

try {
    $db->transactionStart();

    $query = $db->getQuery(true);

    $values = array($db->quote('TEST_CONSTANT'), $db->quote('Custom'), $db->quote('/path/to/translation.ini'));

    $query->insert($db->quoteName('#__overrider'));
    $query->columns($db->quoteName(array('constant', 'string', 'file')));
    $query->values(implode(',',$values));

    $db->setQuery($query);
    $result = $db->execute();

    $db->transactionCommit();
}
catch (Exception $e) {
    // catch any database errors.
    $db->transactionRollback();
    JErrorPage::render($e);
}
13
codinghands

Idealmente, instale pecl, luego extienda la clase JDatabase * apropiada y anule JFactory :: getDbo () con una implementación de lo siguiente para eliminar la necesidad de actualizaciones de código de un billón para envolver todas las consultas críticas de db en las declaraciones try catch.

Lo mejor para mí es el siguiente soporte para la forma antigua y la nueva:

Incluye esto en alguna parte

class jDbUtils
{
    protected static $dbErrorMessage = '';

    public static function stupidJ3CatchDatabaseExecute($db, $cmd, $report = false) {
        self::$dbErrorMessage = '';
        try {
            $res = $db->$cmd();
            // legacy db error support
            if (method_exists($db, 'getErrorNum') && $db->getErrorNum())
                throw new Exception($db->getErrorMsg());
            return $res;
        } catch(Exception $e) {
            self::$dbErrorMessage = $e->getMessage();
            if ($report)
                self::reportIfDbError();
            return false;
        }
    }

    public static function reportIfDbError()
    {
        if (self::$dbErrorMessage) {
            JFactory::getApplication()->enqueueMessage(self::$dbErrorMessage, 'error');
            return true;
        }
    }
}

Entonces úsalo así

function someDbInteraction(){
    $db = JFactory::getDbo();
    $db->setQuery('SELECT no_such_col FROM no_such_table LIMIT 1');
    $res = jDbUtils::stupidJ3CatchDatabaseExecute($db, 'loadResult');
    if (jDbUtils::reportIfDbError())
        return false;
    // do more processing
    return $res;
}
0
ekerner