Created
August 15, 2018 14:53
-
-
Save ddelrio1986/fdbfc0d3362c6efe54edb106b08aa77a to your computer and use it in GitHub Desktop.
PHP error handling (source: http://bestpractices.thecodingmachine.com/php/error_handling.html)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Example of subclassing the base Exception class. Note that it doesn't HAVE to contain any code. | |
class FileWriteException extends Exception { | |
} | |
// Rule: When writing a function, you should throw exceptions for error management instead of returning a | |
// boolean. | |
// Rule: You should never throw Exception class directly. Instead, you should consider extending the Exception | |
// class or using one of the available subclasses. | |
/** | |
* @throws FileWriteException | |
*/ | |
function writeDataInFile(): void { | |
$data = $this->dao->getSomeData(); | |
$result = file_put_contents('date', json_encode($data)); | |
if (!$result) { | |
throw new FileWriteException('Throw my specific exception'); | |
} | |
} | |
// How to catch it. | |
try { | |
writeDataInFile(); | |
} catch (FileWriteException $e) { | |
// Do some specific stuff if we have problems with disk writing. | |
} | |
// Rule: Do not catch exceptions! If something unexpected happens, your code should fail loudly (with a big | |
// error message) rather than trying to hide what is going wrong. | |
// Don't do this | |
function doCleverStuff(): void { | |
try { | |
$results = $this->db->makeRequest("SELECT ...[insert complex SQL here] "); | |
// ... Do stuff | |
} catch (DBException $e) { | |
$this->log->error($e->getMessage()); | |
} | |
} | |
// Do this instead | |
function doCleverStuff() { | |
$results = $this->db->makeRequest("SELECT ...[insert complex SQL here] "); | |
// ... Do stuff | |
} | |
// If you catch the error and log it you then have to wait for someone to see the log full of errors. A SQL | |
// error is a design error and not a runtime error. This is a bug. Don't catch bugs ever! That is evil! | |
// It is okay to catch the exceptions and log them then throw them again. | |
// Rule: When logging exceptions, please log the whole stack trace, not only the message. | |
// Don't do this | |
try { | |
// ... | |
} catch (MyException $e) { | |
// This is bad, you just lost the stacktrace! | |
$this->logger->error($e->getMessage()); | |
} | |
// Do this instead | |
try { | |
// ... | |
} catch (MyException $e) { | |
// This is good, the stacktrace is logged. | |
$this->logger->error($e->getMessage(), [ 'exception' => $e ]); | |
} | |
// Rule: When wrapping exceptions, please pass on the root exception. | |
// Don't do this | |
try { | |
// ... | |
} catch (MyException $e) { | |
// This is bad, you just lost the stacktrace! | |
$this->logger->error($e->getMessage()); | |
} | |
// Do this instead | |
try { | |
// ... | |
} catch (DatabaseException $e) { | |
// This is good. The exception is passed as 3rd parameter of the exception constructor. | |
// Now, your MyServiceException embeds the DatabaseException and both stack-traces will be displayed. | |
throw new MyServiceException("Something wrong happened with the database", 0, $e); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment