简体   繁体   中英

PHP & WP: try catch not working when error from DB is thrown

I'm currently trying to write error handling for the following situation. I want to be able to catch an error when a data base is --read-only and is trying to write.

WordPress database error INSERT command denied to user 'readonly'@

This error is thrown because the database is a --read-only and is trying to write into the database. However, this error should have been caught by my catch conditional.

function drools_request($data, $uid) {
  try {
    $db = _get_db();
    $db->insert("requests", [
      "uid" => $uid,
      "data" => json_encode($data),
    ]);
  }
  catch(Error $e){
    echo 'Error writing to database: ',  $e->getMessage(), "\n";
  }
}

As you see from the above snippet the $db->insert( method correctly breaks because is trying to write into a $db instance that is --read-only . However, the catch(Error $e) did not work, why?

Here is the full class:

    <?php

namespace StatCollector;

function drools_request($data, $uid) {
  try {
    $db = _get_db();
    $db->insert("requests", [
      "uid" => $uid,
      "data" => json_encode($data),
    ]);
  }
  catch(Exception $e)
  {
    echo 'Error writing to database: ',  $e->getMessage(), "\n";
  }
}

function drools_response($response, $uid) {
  try {
    $db = _get_db();
    $db->insert("responses", [
      "uid" => $uid,
      "data" => json_encode($response),
    ]);
  }
  catch(Exception $e)
  {
    echo 'Error writing to database: ',  $e->getMessage(), "\n";
  }
}

function results_sent($type, $to, $uid, $url = null, $message = null) {
  try {
    $db = _get_db();
    $db->insert("messages", [
      "uid" => $uid,
      "msg_type" => strtolower($type),
      "address" => $to,
      "url" => $url,
      "message" => $message
    ]);
  }
  catch(Exception $e)
  {
    echo 'Error writing to database: ',  $e->getMessage(), "\n";
  }
}

function peu_data($staff, $client, $uid) {
  try {
    if (empty($uid)) {
      return;
    }
    $db = _get_db();

    if (! empty($staff)) {
      $db->insert("peu_staff", [
        "uid" => $uid,
        "data" => json_encode($staff)
      ]);
    }
    if (! empty($client)) {
      $db->insert("peu_client", [
        "uid" => $uid,
        "data" => json_encode($client)
      ]);
    }
  }
  catch(Exception $e)
  {
    echo 'Error writing to databse: ', $e->getMessage(), "\n";
  }
}

function response_update() {
  $uid = $_POST['GUID'];
  $url = $_POST['url'];
  $programs = $_POST['programs'];
  if (empty($uid) || empty($url) || empty($programs)) {
    wp_send_json(["status" => "fail","message" => "missing values"]);
    return wp_die();
  }

  try {
    $db = _get_db();
    $db->insert("response_update", [
      "uid" => $uid,
      "url" => $url,
      "program_codes" => $programs
    ]);
    wp_send_json(["status" => "ok"]);
    wp_die();
  }
  catch(Exception $e)
  {
    echo 'Error writing to database: ', $e->getMessage(), "\n";
  }
}

Why is the try and catch not working? What can I do to solve this issue? this post didn't work. PHP try/catch and fatal error

In PHP, both Error and Exception implement the Throwable interface, but an Error is not a subclass of Exception.

You need to use:

catch(Exception $e) ...

Besides that, you should know that PHP database connectors like PDO and Mysqli don't throw exceptions by default. The calling application has to enable exceptions.

Wordpress doesn't enable the database connector to throw exceptions.

See this blog for some examples of error handling in Wordpress:

https://medium.com/the-metric/modern-wordpress-development-you-should-throw-an-exception-when-you-encounter-a-wp-error-81fb82275cbd

WordPress methods like wp_insert_user don't throw exceptions when they fail, but instead — and in some cases only if you tell the method to — return a WP_Error object.

Your code is in a custom namespace:

namespace StatCollector;

so this code:

catch (Exception $ex)

is looking for an exception class of \StatCollector\Exception , which isn't what's thrown: \Exception is.

Since the Error and Exception classes are in the root namespace, you need to do:

catch (\Exception $ex)

and/or:

catch (\Error $ex)

or just:

catch (\Throwable $t)

then also follow Bill Karwin's advice above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM