I apologise if this has already been answered somewhere, but I haven't managed to find an answer so far - maybe I'm searching for the wrong thing!
I am trying to figure out how to handle errors in my OO PHP system, which is used to generate web pages. Hopefully this example will explain what I mean.
Imagine I have a Content class, a Form class and a FormObject class, which hold all the information on page content, web forms and form fields. All classes can run multiple MySQL queries via the DB class. Users can create new content or forms in the back-end. When they do this, I use the classes to create and store the data in the database.
I also have a System class, which is used to generate the web pages. The System class checks what should be displayed on the front-end, builds the appropriate Content and Form objects, then generates the HTML and outputs it to the screen.
I have some checks for serious errors, which stop the code from going any further. However, the problem is that I want to feed back some "soft errors" to the front-end. For example, maybe the System class builds a Form object, which in-turn builds the fields using the FormObject class. The FormObject class queries the database for a field name, but a field name is not found. So the DB class returns an error. I want to be able to feed back a message to the front-end that says the field name has not been found.
What is the best way to get that "soft error" message back to the System class, so it can be outputted to the front-end? I realise it is fairly simple in this particular example, but as more classes are added and, crucially, more levels are added, the problem becomes a bit bigger.
One way I thought of doing this was to have an Error class. The system would create an Error object and pass it on to each Content and Form object as they are created. The Form class would pass the same Error object to the FormItem class. Whenever an error is found, it is logged via a method in the Error class. The system can then access the original Error object and output all the errors. However, as the system grows, more classes are added, and more objects are created, it could get quite confusing. Is there a better way?
You might want to use either
to collect such errors. You then want to use whatever you collected and add it to the output in your System class somehow.
To be more specific...
This is an example for the solution using a global:
global $softErrorMessages = array();
class A
{
function sampleFunctionA()
{
// [...]
// some code setting $result to some valid value
// or to false if an error occured
if($result === false) // check for validity
{
global $softErrorMessages;
$softErrorMessages[] = "The sample function A caused a soft error";
return;
}
// [...]
// some code requiring a valid $result
}
}
If you use such a global, you can then easily access it from your System class and put its contents into the right places of your output.
However, if you perform unit tests, you might not want to use globals or global-like solutions (like singletons). So here is an example for an 'error collection' approach:
class ErrorCollector
{
private $errors = array();
function addError($error)
{
$this->errors[] = $error;
}
function getErrors()
{
return $this->errors;
}
}
class A
{
private $errorCollector;
function __construct(/* your additional parameters */, ErrorCollector $errorCollector)
{
// [...]
// additional instantiation stuff
$this->errorCollector = $errorCollector;
}
function sampleFunctionA()
{
// [...]
// some code setting $result to some valid value
// or to false if an error occured
if($result === false) // check for validity
{
$this->errorCollector->addError("The sample function A caused a soft error");
return;
}
// [...]
// some code requiring a valid $result
}
}
You would instantiate the ErrorCollector only once and then pass it to all other class instantiations. Then you let your objects perform their duties (and possibly add soft errors to the ErrorCollector). Once they're done, your System class would then get all the error messages and - again - place them at the right place of your output.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With