I'm developing a package for Laravel 5 and I'd like to add the rendering logic of my own exceptions to the default ExceptionHandler.
I don't want to replace the default Laravel 5 exception handler, just want to let the application where my package is installed be aware of how my package exceptions should be rendered.
How can I do that? Thank you :)
If you wanted to replace the application exception handler, you could do so in your service provider. While it might be nice to extend from the application exception handler it would be difficult because it might not be named App\Excpetions\Handler if the developers have changed the application namespace.
$app->singleton(
'Illuminate\Contracts\Debug\ExceptionHandler',
'Vendor\Package\ExceptionHandler'
);
Otherwise, you might consider providing a trait that a developer can pull into their own ExceptionHandler and leverage your additional functionality that way.
Related
I have written my own logging class that I defined as a service and placed inside the AppBundle\Services namespace. I can access it easily inside the controller when I want to log something, but what about accessing it from other services?
I'd have to pass the logging service as a dependency injection, but what if I have more than 100 services defined (services, modules, event listeners etc. etc.), each of them having their own dependencies? It would create a mess.
I've been also thinking about extending some core service that defines the logging service, but then again - all my services, modules, event listeners, would have to extend one core class.
What's the best approach to solve this?
May be a good approach would be to rethink responsibilities in order to avoid the creation of too many services.
About the fact of consumming service itself, I think there are no problem to reuse as much as you need along the application lifecycle. In fact, symfony will handle the instantiation and you will be only consumming it as a service.
Another approach will be to create base classes for all your core objects, let these base classes to handle log services and final classes will log in a implicit way. This will not save service calls but almost will leave you to handle it manually.
If you think you will use your log feature in several projects then I recommend you to move to vendors folder and use it as external module, synchronised via composer to your github account. It will be like your own 3rd party product.
If you are not a symfony friend then you can break the law and create your own singleton pattern available by autoloading, but I think you should take advantage of the powerfull symfony service structure.
The main Laravel application object has two methods, booting and booted. These methods allow you to configure callbacks. The application object will call these callbacks before and after it boots.
Where, as a Laravel application developer, can I hook into these events? Looking at the framework it seems like
bootstrap/start.php
is the obvious place — but if I put code here it'll be zapped in the next update. There's also
start/global.php
statt/{$env}.php
but these files are actually required in by a booted callback, which means the booting callback point would be unavailable.
Is there an intended place for me to hook into these events as a Laravel application developer? Or are booting and booted there for the core framework developers? Or has I made an incorrect assumption that I'm not even aware of? Laravel 4.2.6, but if there's context from additional versions I'd love to hear about it.
New to Laravel, not new to programming. Not asking for a specific task (yet), just getting a feel for what best practices/intended use is and is not.
As a formal answer, there's no defined place for this behaviour. But a note against your comments about start.php, this file will not be "zapped" when you update laravel.
As long as a file is not within the vendors folder, any laravel updates won't change your files. start.php is generated when you create a base project, but should not be changed with further updates.
composer create-project is responsible for creating your base "skeleton" application, and any composer update that you do will just modify files in the vendor folder. Just remember, do not modify files in the vendor folder and you will be fine!
I'm trying to build a specific error "stack" for my applications. I have a small module system in place, and I want to be able to add the error handlers from the module to the current error stack. However, there are some error handlers that I want to be checked before the module error handlers, but those need registered before the module error handlers, in case there is in error in the module's bootstrapping process.
The stack I'm going for looks like:
Logging Error handlers
Alert Error handlers (firing off emails to developers if necessary)
Module error handlers
Application error handlers
Default fallbacks
When the application starts, the logging, alert, and default fallbacks are placed on the stack immediately. I want to be able to stub the application error handlers in next, and then the module error handlers once the module is determined and loaded. As far as I can see, error handlers can only be placed on the top or bottom of the stack; not inserted in the middle.
Is there a way to insert into the error handler? If not, is there a way to register a different error handling class (one extended from the built-in one)?
In the interest of time, I managed to come up with a solution that works. It's not what I was really looking for, but I'll share it in case anyone else needs to do something like this.
My approach was to extend the Illuminate\Foundation\Application and override the registerExceptionProvider() method to register my own ExceptionServiceProvider. This provider extends from Illuminate\Exception\ExceptionServiceProvider and overrides the registerHandler() method. In there, I register my Handler in the same manner the original provider registers the default handler.
I added insert* versions of each of the error methods provided by the default Application and an insertError method to the Handler that does the actual insert into the error handler stack. Lastly, I altered the start.php file to create my Application instead of the default one.
As I mentioned, I don't really like this approach; I feel it's more heavy lifting that what should have to be done. It seems like Laravel should have a better way to extend the actual error handler, or at least an interface to order the error handlers being registered more precisely.
How, if at all, should a Symfony 2 bundle developer use the event dispatcher(s) that ship with a stock Symfony 2 system?
I've been digging around in the source for Symfony's event dispatcher, and some of what I've seen has me a little confused as to how I, a third party bundle creator, should use the event dispatcher that ships with Symfony.
Specifically, I noticed that a stock Symfony system has two event dispatcher services. The event_dispatcher and the debug.event_dispatcher. Which service the HttpKernel uses is dependent on environment, and driven by the generated dev or prod container file.
//dev kernel instantiation uses `debug.event_dispatcher` service
new \Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel(
$this->get('debug.event_dispatcher'),
$this,
$this->get('debug.controller_resolver')
);
//prod kernel instantiation uses `event_dispatcher` service
new \Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel(
$this->get('event_dispatcher'),
$this,
new \Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver($this, $this->get('controller_name_converter'), $this->get('monolog.logger.request', ContainerInterface::NULL_ON_INVALID_REFERENCE)));
So far this all makes sense — as it's the debug.event_dispatcher that implements functionality in the web profile's event's tab, including the ability to see which listeners were called, and which listeners were not called.
However, I noticed most (if not all) third party bundles use a hard coded event_dispatcher service call. For example, the JMS/JobQueueBundle uses the following
$this->dispatcher = $this->getContainer()->get('event_dispatcher');
Events dispatched like this fire correctly, but the debug.event_dispatcher doesn't know about them, which means the Symfony web profiler will incorrectly list a called listener as uncalled. Additionally, it's not clear how a bundle author could avoid this, as they don't have the advantage of generating a container file and the HTTP Kernel object doesn't expose an accessor for the protected dispatcher object.
So, is this a bug in Symfony?
Or is the event_dispatcher service only intended for Kernel events, meaning all those bundle authors are misusing it?
Or (the most likely candidate), is it something else I'm missing or haven't considered?
It looks like the scenario I described above doesn't apply to that latest version of Symfony (2.4.1). Specifically, in 2.4.1, the generated app container file
app/cache/dev/appDevDebugProjectContainer.php
contains the following
$this->aliases = array(
//...
'event_dispatcher' => 'debug.event_dispatcher',
//...
);
That is, unlike the Symfony 2.3.6 project I was working on, the event_dispatcher service has been aliased to the debug.event_dispatcher service (when Symfony runs in development mode). This means when other bundles ask for an event_dispatcher service in dev mode, they're really getting a debug.event_dispatcher service. This lets the the debug.event_dispatcher know about all the events, and it can correctly report on which ones were dispatched.
While it's not a concrete answer, it does indicate the Symfony team was/is aware of the issue, which leads me to believe it's their intention for Bundle developers to use the event_dispatch service fro their own events.
In web frameworks I've built and used in the past, there's been some means to specify some form of "last resort" error handler. I'd appreciate any help in determining how to accomplish that goal using CodeIgniter, which is a legacy part of a product I'm working on.
The goal of the last resort error handler is to capture any exception that's bubbled up, unhandled, from the application logic. Since, at this high framework level, the handler can't resolve the exception, a typical implementation is to log the error (with associated context) and present a user-friendly error page rather than a scary, technical exception page.
I wasn't able to find support in the CodeIgniter documentation, but I expect there must be support for this. Did I not find support because I should use PHP's set_error_handler() and set_exception_handler()? (I'm new to PHP, but expert in Java, Ruby/Rails.)
Thanks in advance for you guidance!
It seems CodeIgniter 2.0+ registers the handlers you specified to load the CI_Exceptions class. I usually put a MY_Exceptions library in the application/libraries folder to "catch" them before CodeIgniter. I'd rather handle them gracefully than let CI show it's error pages.