I have a question regarding error handling in Zend. I am fairly new to zend frame work.
I am new on this project that i am working on and the previous developers didn't handle service errors and the application is fairly large so I am trying to figure out an easy way to handle all the errors the service returns, and even handle the errors when service fails.
so when ever there is an error we need to alert the user that something is wrong and show the error.
now since i will be getting that in Model, how do I handle this in elegant way so that there is not much rework to be done.
Can i create a common class and extend it? I also need to alert the user in case of any error.
I want a better way because I have more than 150 controller files and about more than 100 model files.
Thanks
For a ZF app that's using Zend_Application, you should ensure that your application.ini file has this in it:
resources.frontController.throwExceptions = false
Then any Exception that is thrown will be trapped and the ErrorController's errorAction() method will be called. This gives you a centralised place to handle errors.
Related
As shown in the php documentation is it possible to create your own exception handler. I see this as a reasonable way to handle my user generated errors and exceptions throughout the project I am working on. Through research I have made a decent amount of progress in implementing a specific one, just for one class, including things like using ErrorException (from the first answer) and making sure to return false for error levels that I can't handle.
I have however run into a wall with making it more generic. I don't want to have to write a separate handler for every class I write (especially because the vast majority of that code is going to be the same for every one). Yet it feels like terribly bad practice to have every single error for the entire project in the same handler.
The closest I have gotten to what feels like an acceptable solution is to write a subclass of ErrorException for every class I want to handle the errors for and store messages in each of those. But even with this I am probably going about it wrong (I don't think that would be the proper place to store default error messages). Is there a universally accepted way of doing this that I have been unable to find? or is one of these ways actually the way it's generally done? or are there multiple solutions that are scalable based on the size of the project?
EDIT: Just realized I can write a generic Exception_Handler with the reused code and extend it for each set of errors I have (real herp moment for me), but it still seems like I should handle all errors in the same place. If I'm completely wrong, let me know.
EDIT 2: Decided to go with a config file containing the error messages for each class that will throw errors, then the name of the class that throws the error defines what config file is loaded to get the list of messages associated with error number. This also allows me to easily define messages that should get logged as opposed to messages that should get sent to the user (essentially specific vs. generic messages).
I guess I'll mark this as answered or something, but if I'm doing something wrong feel free to let me know, help is always appreciated.
Decided to go with a config file containing the error messages for each class that will throw errors, then the name of the class that throws the error defines what config file is loaded to get the list of messages associated with error number. This also allows me to easily define messages that should get logged as opposed to messages that should get sent to the user (essentially specific vs. generic messages).
More specifically I'll probably use an ini file that defines an array of arrays where each number contains the array of error messages for that error number. Then use a foreach with the thrown error numbers to return the error message(s).
I've created a simple class LogHelper with a static method that I call within my application. I can call it as follows:
LogHelper::writeToErrorLog($config->getLogPath(), $exception); or
LogHelper::writeToErrorLog($config->getLogPath(), $exception, $config->getLogFile);
The writeToErroLog method will generate a log filename if one isn't passed into it.
I have another class called Config, which basically takes an XML file and exposes the values via getters & setters. This is initialised at the start of the app & contains the log path where the error logs need to be written to.
My requirements are that I create one log file with the same filename per run of the application. When the app ends the logs, if populated, will be emailed.
My application has numerous other classes for DB, parsing data, formatting data, etc... all requiring logging at some point. The majority of my errors will come from exceptions thrown which will bubble up to the parent class, caught & handled by the LogHelper. There will be several cases where I don't want to throw exceptions and will just want to log information or errors.
My concern is that I feel like I'm constantly passing the config to every class that requires logging, which feels wrong. In addition I only want to be setting the filename for the error log once. Is there any best practice way of approaching this?
TIA
Stuff
Have you considered using set_exception_handler()? You wouldn't have to put the logger in every class, it would simply handle all uncaught exceptions. You could call it within your bootstrapping process or some other application initialization spot as such:
set_exception_handler(array("MyClassName", "functionNameHere"));
Inside that function you could call LogHelper::writeToErrorLog().
I have a problem with the error page 500 of symfony (apps/%app-name%/config/error/error.html.php).
I had to learn that symfony skip the standard way of page creation completely. I had to organize all the helpers myselve.
require_once dirname(__FILE__) . '/../../../../lib/vendor/symfony/lib/helper/HelperHelper.php';
use_helper('Tag', 'Asset', 'Url', 'I18N', 'Date', 'Partial');
But now I am missing the contents of the configuration. How can I manually trigger the autoloader mechanism, so that I get the information from view.yml and so on?
I don't know if it's smart to depend on the whole Symfony stack when you're displaying an error.
IMHO the error pages need to be designed as light-weight as possible, 99% static HTML, with only some php code to display a friendly error message.
Because, what if something is wrong with your Symfony stack, then you can't even present a decent error page to the user.
The 500 error page is also a "hard fail" page, it is the most generic error handler which is only shown if no action tried to catch the exception.
In the cases where you want to use the view and everything, I think it's better to catch the exceptions right there in the action, and present better error pages (return sfView::ERROR) with information the user can act on.
I am trying to build a custom MVC framework in PHP. I'm just starting out with this MVC and framework stuff and I'm not very good.
I created all the general stuff. The library for the model, controller and view and I got a general app up and running.
I would like to now incorporate some error handling. Primarily on the user side for bad urls. I want to make Page Not Found or 404 Errors. So i need a way to check for bad controllers,actions and query strings. And then send the users to a 404 page.
What is the best practice for doing this in an MVC environment?
EDIT
This is a learning based project it is not for production.
First of all it is not recommended to develop a custom framework your own if you are planning it for production. There are many great frameworks that you can make use of, with good flexibility and more importantly with more performance.
Coming to the problem. First write a custom exception handler for managing 404. I recommend to call them in your system/core class where you create Object of the controller and invoke the action, if they dont exists.
Add an error handler in your bootstrap.
For example, in mine I have:
public function error(){
$this->view->msg = 'Page not found';
$this->view->render('error/index');
}
Add a check for the method in the bootstrap. Where depends on your structure. If the method or controller isn't found call the error() method.
Thats probably the simplest way.
you can use .htaccess (if using apache) to route all request to your index page. Usually the the controller (and action), view is associated with a file or function. so, if you want to show custom error message, just check for the file, class, or its methods.
for example:- index.php?controller=control1&action=action1.
if(!file_exists('control1.php'))
if(!method_exists($controller, 'action1'))
//route to error handler
Well, if you are learning like you said, you shouldn't use your framework for production code because one thing is breaking the app at home and another one is loosing money with angry clients :)
Back to the problem. I've built my own custom framework for PHP applications and I have in my framework several Routers. The idea is that each Router handles a specific pattern of Route, like this:
http://someapplication.org/services/awebservice/
This code would call the ServiceRouter, which handles Routing web services. Before calling any Router I check if the Router exists, and if it does, then I would call a method to check if the route is valid, something like this:
if ( RoutingManager::RouterExists($route) )
{
$router = RoutingManager::GetRouter($route);
if ( !$router->IsValid )
RoutingManager::RedirectTo404();
}
The idea is to locate your 404 handler to a class, and delegate the task of routing into different classes to allow a variety of Routers and make your application more changeable (scalable)
Hope I can help!
I asked around on various IRC channels but was unable to get an answer with a definitive explanation behind it. Should errors (pertaining to the model, such as transaction failures) be handled in the model, or in the controller?
Thanks in advance for any help.
EDIT
Well, the confusing thing is that my code (in the model) looks something like this already:
try
{
// Connect to MongoDB
// Fetch a record
}
catch (MongoConnectionException $e)
{
// Handle this error
}
catch (MongoException $e)
{
// Handle this error
}
So, should I return exceptions based on the exceptions MongoDB returns? Or should I directly allow these exceptions to bubble up to the controller?
Thanks!
The correct answer is "Both", but mostly in the Model.
The appropriate thing for your controller to do is simply catch some exception that the model throws, and handle outputting a nice "whups" message. Depending on how you're structuring your models, it might be appropriate for the controller to do some logging.
Anything other than catching the exception, maybe writing to a log (if your model infrastructure doesn't do it), and displaying a pretty error, does not belong in your controller.
Errors such as a transaction failure - and what to do in such cases - are business logic issues. Thus, they should be handled in the model and appropriate notifications passed back up to the controller.
Fat model, skinny controller.
In most cases, you should throw or pass exceptions to the caller/receiver AKA Controller or BLL.
It's controller's job to process actions not model
It's view's job to display a message box(or whatever) not model
You can't HANDLE exceptions in model, for real... you can only log or throw them.
Scott Guthrie for ASP.NET C# suggests using the Controller as the exception handler. He also, suggests setting up helper objects and handlers for the project. This in turn allows you to continue your development as normal.
Note, however with PHP MVC is still in its earliest stages and implementation so, this may not be perfect.
I do think that once you have decided how to handle the solution that you still with it and follow that pattern once you have made the decision.
The ideas behind MVC frameworks are quite simple and extremely flexible. The idea is that you have a single controller (such as index.php) that controls the launch of applications within the framework based on arguments in the request. This usually includes, at a minimum, an argument defining which model to invoke, an event, and the usual GET arguments. From there the controller validates the request (authentication, valid model, request sanitization, etc.) and runs the requested event.
At present the are only really two true frameworks...and this could be a problem for coding, support and future releases. Though, there are alot of frameworks that extend themselves to support MVC.
By Earliest stages, I mean to say and suggest that the current frameworks, solutions and support is limited as a result of rushed deliveries and poor documentation. Additionally, I'm suggesting what works for me and has worked for me in the past.
I would strongly This Website