26

I have a page on my website (high traffic) that does an insert on every page load.

I am curious of the fastest and safest way to (catch an error) and continue if the system is not able to do the insert into MySQL. Should I use try/catch or die or something else. I want to make sure the insert happens but if for some reason it can't I want the page to continue to load anyway.

... $db = mysql_select_db('mobile', $conn); mysql_query("INSERT INTO redirects SET ua_string = '$ua_string'") or die('Error #10'); mysql_close($conn); ... 
2
  • On the use of "or die": phpfreaks.com/blog/or-die-must-die Commented Dec 17, 2009 at 0:55
  • 1
    As for exceptions vs checking return values, it depends on how many points might generate errors. With one or two points, I'd go with error checking, as it's more performant and just as readable in this case. Once you hit three or more error checks in a code block, exceptions become more readable. It's all about reducing cyclomatic complexity. Note that this covers the point you handle the error; if you're talking about signaling errors, you'll wind up with different guidelines. Commented Dec 17, 2009 at 0:59

10 Answers 10

25

Checking the documentation shows that its returns false on an error. So use the return status rather than or die(). It will return false if it fails, which you can log (or whatever you want to do) and then continue.

$rv = mysql_query("INSERT INTO redirects SET ua_string = '$ua_string'"); if ( $rv === false ){ //handle the error here } //page continues loading 
Sign up to request clarification or add additional context in comments.

2 Comments

I don't think mysql_query throws an exception.
Indeed, neither mysql_query nor mysqli_query throw an exception. PDOStatement::execute will, but only if you call PDO::setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) before calling PDOStatement::execute.
11

This can do the trick,

function createLog($data){ $file = "Your path/incompletejobs.txt"; $fh = fopen($file, 'a') or die("can't open file"); fwrite($fh,$data); fclose($fh); } $qry="INSERT INTO redirects SET ua_string = '$ua_string'" $result=mysql_query($qry); if(!$result){ createLog(mysql_error()); } 

1 Comment

i am, in principle, not a fan of [or die].
10

You can implement throwing exceptions on mysql query fail on your own. What you need is to write a wrapper for mysql_query function, e.g.:

// user defined. corresponding MySQL errno for duplicate key entry const MYSQL_DUPLICATE_KEY_ENTRY = 1022; // user defined MySQL exceptions class MySQLException extends Exception {} class MySQLDuplicateKeyException extends MySQLException {} function my_mysql_query($query, $conn=false) { $res = mysql_query($query, $conn); if (!$res) { $errno = mysql_errno($conn); $error = mysql_error($conn); switch ($errno) { case MYSQL_DUPLICATE_KEY_ENTRY: throw new MySQLDuplicateKeyException($error, $errno); break; default: throw MySQLException($error, $errno); break; } } // ... // doing something // ... if ($something_is_wrong) { throw new Exception("Logic exception while performing query result processing"); } } try { mysql_query("INSERT INTO redirects SET ua_string = '$ua_string'") } catch (MySQLDuplicateKeyException $e) { // duplicate entry exception $e->getMessage(); } catch (MySQLException $e) { // other mysql exception (not duplicate key entry) $e->getMessage(); } catch (Exception $e) { // not a MySQL exception $e->getMessage(); } 

4 Comments

@Anonymous, there is a slightly different approach here - you just throw a generic exception and you don't know which kind of an exception is thrown. Of course you can pass errno as $code (2nd param for Exception) and check it in catch block, but it's not that comprehensive. That's why I wrote this answer despite there are already 2 answers on this question exploiting wrapper for mysql_query throwing expcetion. So, yes, it's similar, but not exactly the same conceptually.
I understand, yours comprehends on types of errors, while mine is exclusively for the easy of use. :)
easy of use is so person-dependent term. I'd rather use my code (I actually have my own ORM with it's own exceptions), especially in large projects because of it's ease of use. John Doe can go with your solution because of ease of use. And we both will be right to chose whatever solution fits our needs best, right?
@Nemoden: shouldn't it be "try { my_mysql_query(..."?
5

if you want to log the error etc you should use try/catch, if you dont; just put @ before mysql_query

edit : you can use try catch like this; so you can log the error and let the page continue to load

function throw_ex($er){ throw new Exception($er); } try { mysql_connect(localhost,'user','pass'); mysql_select_db('test'); $q = mysql_query('select * from asdasda') or throw_ex(mysql_error()); } catch(exception $e) { echo "ex: ".$e; } 

3 Comments

mysql function are not throwing any exceptions.
Great example, this seems to be the most proper way to do it, and I'm going to stick with it too. The advantage is obvious - you will realize when you'll have to do 5 queries in one block and get the hell out if any of them fails with an exception. I would elaborate on that for a bit though.
Good example and good way, result for my case: ex: exception 'Exception' with message 'Duplicate entry '4' for key 'PRIMARY'' in . Thank you
3

Elaborating on yasaluyari's answer I would stick with something like this:

We can just modify our mysql_query as follows:

function mysql_catchquery($query,$emsg='Error submitting the query'){ if ($result=mysql_query($query)) return $result; else throw new Exception($emsg); } 

Now we can simply use it like this, some good example:

try { mysql_catchquery('CREATE TEMPORARY TABLE a (ID int(6))'); mysql_catchquery('insert into a values(666),(418),(93)'); mysql_catchquery('insert into b(ID, name) select a.ID, c.name from a join c on a.ID=c.ID'); $result=mysql_catchquery('select * from d where ID=7777777'); while ($tmp=mysql_fetch_assoc($result)) { ... } } catch (Exception $e) { echo $e->getMessage(); } 

Note how beautiful it is. Whenever any of the qq fails we gtfo with our errors. And you can also note that we don't need now to store the state of the writing queries into a $result variable for verification, because our function now handles it by itself. And the same way it handles the selects, it just assigns the result to a variable as does the normal function, yet handles the errors within itself.

Also note, we don't need to show the actual errors since they bear huge security risk, especially so with this outdated extension. That is why our default will be just fine most of the time. Yet, if we do want to notify the user for some particular query error, we can always pass the second parameter to display our custom error message.

Comments

2
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); 

I am not sure if there is a mysql version of this but adding this line of code allows throwing mysqli_sql_exception.
I know, passed a lot of time and the question is already checked answered but I got a different answer and it may be helpful.

3 Comments

Yes, you may have different answer. Please add more details to the answer like where to add the line of code and a link explaining the code in detail?
As long as it's used in the php file you may be able to catch the mysqli_sql_exceptionS.
since mysql has been removed in PHP 7.0 one should/needs to use the mysqli stuff. see also the answers here with some more explanations: stackoverflow.com/questions/14578243/…
1
 $sql = "INSERT INTO customer(FIELDS)VALUES(VALUES)"; mysql_query($sql); if (mysql_errno()) { echo "<script>alert('License already registered');location.replace('customerform.html');</script>"; } 

Comments

0

To catch specific error in Mysqli

 $conn = ...; $q = "INSERT INTO redirects (ua_string) VALUES ('$ua_string')"; if (mysqli_query($conn, $q)) { // Successful } else { die('Mysqli Error: '.$conn->error); // Show Error Complete Description } mysqli_close($conn); 

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
-1

Use any method described in the previous post to somehow catch the mysql error.
Most common is:

$res = mysql_query('bla'); if ($res===false) { //error die(); } //normal page 

This would also work:

function error() { //error die() } $res = mysql_query('bla') or error(); //normal page 

try { ... } catch {Exception $e) { .... } will not work!

Note: Not directly related to you question but I think it would much more better if you display something usefull to the user. I would never revisit a website that just displays a blank screen or any mysterious error message.

Comments

-1
$new_user = new User($user); $mapper = $this->spot->mapper("App\User"); try{ $id = $mapper->save($new_user); }catch(Exception $exception){ $data["error"] = true; $data["message"] = "Error while insertion. Erron in the query"; $data["data"] = $exception->getMessage(); return $response->withStatus(409) ->withHeader("Content-Type", "application/json") ->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); } 

if error occurs, you will get something like this->

{ "error": true, "message": "Error while insertion. Erron in the query", "data": "An exception occurred while executing 'INSERT INTO \"user\" (...) VALUES (...)' with params [...]:\n\nSQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: \"default\"" } 

with status code:409.

1 Comment

Error is misspelled. "Erron in the query"

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.