Comments (16)
Yii may introduce its onw 'application end' callbacks list to be used instead of register_shutdown_function()
and will be invoked at the application run ending. Thus saving session, writing logs and so on should be performed through it.
But in case developer uses some 3rd party library, which relies on register_shutdown_function()
those callbacks will drop out of Yii error handling or logging.
Also developer will be stripped of ability to terminate script flow using exit
or die
operators, as thier invocations will prevent Yii ending callbacks to be executed, meaning no session will be written no logs flushed and so on.
It is a side effect that changes global state.
If you concern about about error handler remains registered after application running is complete, you can always invoke ErrorHandler::unregister() after application run:
$config = require(__DIR__ . '/../config/frontend.php');
(new yii\web\Application($config))->run();
Yii::$app->errorHandler->unregister();
//script continues
from yii-core.
I was just looking into this, some more, what is your opinion on removing the global exception handler after application initialization?
Currently the global registration via set_exception_handler
is a side effect.
While there might be cases where we need it (during init or bootstrap), as soon as we enter run()
:
try {
$this->state = self::STATE_BEFORE_REQUEST;
$this->trigger(self::EVENT_BEFORE_REQUEST);
$this->state = self::STATE_HANDLING_REQUEST;
$response = $this->handleRequest($this->getRequest());
$this->state = self::STATE_AFTER_REQUEST;
$this->trigger(self::EVENT_AFTER_REQUEST);
$this->state = self::STATE_SENDING_RESPONSE;
$response->send();
$this->state = self::STATE_END;
return $response->exitStatus;
} catch (ExitException $e) {
$this->end($e->statusCode, isset($response) ? $response : null);
return $e->statusCode;
}
We could add another catch
statement from which we invoke the error handler.
from yii-core.
- I see no pros compared to handling exceptions via
set_exception_handler
. - There are still exceptions outside
run()
to be handled.
from yii-core.
It is a side effect that changes global state.
from yii-core.
Alright. How would you deal with exceptions outside of run()
method then?
from yii-core.
Haven't said I have it all figured out ;).
We have 4 phases
- before construction
- construct / init
- run
- after run
The first and last one are technically out of scope of the app; currently we can't handle 1 but we do handle 4.
We need to solve step 2, 4 is easy. One simple solution is to register the exception handler and unregister it at the end of the init phase.
Mostly I feel having special components is a code smell. And I'd like to gather some more opinions on this case.
from yii-core.
@yiisoft/core-developers, @yiisoft/reviewers ?
from yii-core.
There are also 'shutdown' functions. which are run on script termination outside of the application scope.
They may trigger extra errors. Having error handler attached all the time is an insurance every error including ones causes by application destruction (e.g. at Application::__destruct()
and destructor of any internal object) or at shutdown function will be at least logged.
from yii-core.
That's a good point; destruction matters as well.
from yii-core.
Wrapping Application::run()
into a try...catch
is unlikely to suffice.
At the present state error handler is registered during Application
instance creation, e.g. at Application::__construct()
. It is registered before other components and other application initialization code, thus it is able to handle any error or exception causes by application internal components processing. Thus global try...catch
should cover application construction as well, which demands creation of another static method for application run:
class Application extends Module
{
public static function runApp($config)
{
try {
$app = new static($config);
$app->run();
} catch (\Throwable $e) {
if (isset($app) && isset($app->errorHandler)) { // error may occur before application created or error handler initialized
$app->errorHandler->handleException($e);
} else {
throw $e;
}
}
}
}
// file `index.php`
$config = require(__DIR__ . '/../config/frontend.php');
yii\web\Application::runApp($config);
For my taste this looks a little ugly.
from yii-core.
Updated https://github.com/yiisoft/yii2/blob/master/docs/internals/design-decisions.md since, because of things mentioned by @klimov-paul, handler is unlikely to be done in another way.
from yii-core.
Can this be moved to yiisoft/yii-core?
I would like to revisit this for 3.0.
While I understand the arguments given for the current implementation I feel we can do better.
Even if we decide that error handler needs to be attached early and stay alive after application finishes, we can improve:
- The error handler should not be a component, it doesn't make sense to have multiple error handlers; also a component
- Handling application errors by attempting to run a different route is questionable at best; we do not know the state of our application, so running actions is probably not the best approach. (
yii\web\ErrorHandler::$errorAction
) - We should offer the user the option to not have side effects when using the error handler
register_shutdown_function
. - The
errorHandler
is currently registered inApplication::run()
based on the value of a constant. If we are usingerrorHandler
as a component then we should instead support disabling it via configuration. - The error handler should be able to be used without
register_shutdown_function
. - There should be a setting that unregisters the error handler after
run()
. - Code should not be using
register_shutdown_function()
but instead use Yii application events.
from yii-core.
Why closing?
from yii-core.
Hmm, was writing a post and then decided not to post it; clicked close instead of closing the page :|
Could you move this to core?
from yii-core.
Done.
from yii-core.
Re-checked everything and now consider it done: https://forum.yiiframework.com/t/error-handler-is-back/126667
from yii-core.
Related Issues (20)
- 我认为yii3最应该解决的就是composer包过大的问题 HOT 2
- Should not require yii-web HOT 11
- Enhancement: BaseJson::decode supports decode options HOT 1
- Discuss: Do we still need controllers? HOT 2
- Enhancement: StringHelper::isEmpty() HOT 7
- can't visit yii forum site HOT 1
- Review helpers naming and usage HOT 33
- Url::ensureScheme should fail hard for non absolute paths HOT 2
- What is the current dependency between repo? HOT 20
- Yii3 assets path not correctly reference if installed in subfolder HOT 2
- SOLID compliance HOT 3
- cannot use @web or @webroot in config. HOT 53
- Deal with relative links in Formatter::asUrl() HOT 4
- Nested model attribute label issue HOT 12
- Custom reference syntax to class or class member in comments make impossible to navigate in IDE HOT 19
- Change namespace to Yiisoft\Core? HOT 8
- When will yii3 be released? HOT 1
- Request to separate FileHelper from yii-core HOT 19
- Pack requirements checker into separate package HOT 1
- Repo merges into a repo and then splits HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from yii-core.