web-dev-qa-db-fra.com

Pourquoi dbDelta () ne récupère-t-il pas les erreurs Mysql?

De ce que je peux voir, dbDelta() est conçu pour supprimer les erreurs de base de données qui surviennent pendant son fonctionnement. D'une manière générale, cela semble être le cas, mais New Relic rapporte toujours MysqlErrors de la fonction. Le message d'erreur exact est du format:

MysqlError: Table 'xxx.wp_yyy_posts' doesn't exist

De dbDelta() dans /wp-admin/includes/upgrade.php, nous avons:

// Fetch the table column structure from the database
$suppress = $wpdb->suppress_errors();
$tablefields = $wpdb->get_results("DESCRIBE {$table};");
$wpdb->suppress_errors( $suppress );

Il semble que suppress_errors() effectue son travail et empêche les messages d'erreur d'être renvoyés à l'écran. Cependant, il semble également que ces erreurs ne soient pas réellement traitées, comme le montre notre installation de New Relic.

Naturellement, nous aimerions éliminer toutes les sources d'erreurs possibles sur notre application de production afin de pouvoir utiliser avec précision l'outil New Relic pour suivre les taux d'erreur réels et les associer aux outils de génération de rapports de New Relic.

Y a-t-il une raison impérieuse pour laquelle dbDelta() ne traite pas cette erreur? La seule raison pour laquelle je peux penser est qu'il s'agit d'une décision de conception délibérée facilitant le développement et la correction des bogues. Il peut être difficile pour un développeur de localiser des problèmes lorsque dbDelta() supprime complètement les erreurs. Bien sûr, un nouveau paramètre/option pourrait être introduit pour spécifier si cette suppression automatique des erreurs devait avoir lieu ou non (ce qui ferait de la capture de MysqlError une évidence).

Cela devient un problème dans notre cas où chaque appel à install_blog() génère cette erreur. Étant donné que nous exécutons une installation multisite volumineuse, chaque fois que nous créons un nouveau blog, une erreur est générée.

3
rinogo

Comme mentionné par @Charleston Software Associates, la requête DESCRIBE ne doit pas être exécutée si la table n'existe pas. La meilleure solution, a-t-il souligné, consiste à éviter que l'erreur ne se produise.

Pour ce faire, corrigez wp-admin/includes/upgrade.php comme suit:

Modifiez la ligne suivante de dbDelta ():

  $tablefields = $wpdb->get_results("DESCRIBE {$table};”);

à:

    //Begin core hack - See http://wordpress.stackexchange.com/q/141971/10388
    $check_table = $wpdb->get_results("SHOW TABLES LIKE '".str_replace("_", "\_", $table)."';");
    if(!empty($check_table))
        $tablefields = $wpdb->get_results("DESCRIBE {$table};");
    else
        $tablefields = null;
    //End core hack

Ce n'est pas la solution la plus propre (surtout depuis que c'est un hack fondamental), mais ça fonctionne pour moi, au moins! Cela aidera peut-être quelqu'un d'autre.

UPDATE: Voir mon commentaire ci-dessous. (Cela ne résout pas complètement le problème, bien que ce soit un pas dans la bonne direction)

1
rinogo

Les erreurs de base de données de ce type ne doivent apparaître sur l'interface utilisateur que si DB_DEBUG est activé. Sur un système de production qui devrait être désactivé. Vous devriez trouver ce paramètre dans le fichier wp-config.php pour votre installation WP.

Vous pouvez essayer de forcer manuellement les erreurs à "masquer" en réinitialisant le paramètre global EZSQL_ERROR. Ceci est mon hack personnel et probablement pas recommandé ou meilleure pratique pour travailler avec dbDelta:

/**
 * Update the data structures on new db versions.
 *
 * @global object $wpdb
 * @param type $sql
 * @param type $table_name
 * @return string
 */
function dbupdater($sql,$table_name) {
    global $wpdb;
    $retval = ( $wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name ) ? 'new' : 'updated';

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    $were_showing_errors = $wpdb->show_errors;
    $wpdb->hide_errors();
    dbDelta($sql);
    global $EZSQL_ERROR;
    $EZSQL_ERROR=array();
    if ( $were_showing_errors ) {
        $wpdb->show_errors();
    }

    return $retval;
}
0
Lance Cleveland