Closed
Description
This one is similar and psalm thinks that
trigger_error
makes the code exit I suppose:
https://psalm.dev/r/38c501845b
Ref: #6109
Originally posted by @orklah in #6109 (comment)
This one is similar and psalm thinks that
trigger_error
makes the code exit I suppose:
https://psalm.dev/r/38c501845b
Ref: #6109
Originally posted by @orklah in #6109 (comment)
Activity
psalm-github-bot commentedon Jul 15, 2021
I found these snippets:
https://psalm.dev/r/38c501845b
orklah commentedon Jul 15, 2021
@muglug @weirdan Do you have an opinion?
Psalm considers that trigger_error stop the execution here
psalm/src/Psalm/Internal/Analyzer/ScopeAnalyzer.php
Line 107 in 0a7d254
but not everywhere. (see #6109). What should be the correct behaviour?
williamdes commentedon Jul 15, 2021
Note: we custom handle calls for trigger_error
weirdan commentedon Jul 18, 2021
trigger_error()
return type (specifically cases when it returnsnever
) depends on the error handler behaviour. Since that's external to Psalm and cannot be easily inferred, Psalm should have a sensible default matching default error handler behaviour and let users override that. I see two options here:trigger_error()
and use the stub signature consistently. In practice this means we need to remove hardcoded handling we have currently, and just provide a default, overridable, stub.trigger_error()
return type from that. It would also allow enforcing error handler compatibility.orklah commentedon Jul 18, 2021
I like the second option. trigger_error has a default behaviour that is valid for a lot of project that don't touch set_error_handler and when the error_handler use the same behaviour as the default one.
That means we could have an option whose default means that Psalm will use the default behaviour of trigger_error. Other values for this option could be "none" where trigger_error never
die
and "always" where it alwaysdie
.I think this could be handled with a return type provider accessing config, right?
weirdan commentedon Jul 18, 2021
Sounds good.
This sounds sensible, but so is assuming
trigger_error(..., E_USER_ERROR)
never returns 🤷.Let's explore the problem space:
There are four possible values for
$error_level
:E_USER_ERROR
,E_USER_WARNING
,E_USER_NOTICE
andE_USER_DEPRECATED
. Default return type fortrigger_error()
is@return ($error_level is E_USER_ERROR ? never : true)
. Theoretically speaking, someone could have a custom handler resulting in@return ($error_level is E_USER_DEPRECATED ? never : true)
, i.e. continue on everything but deprecation errors and your approach would not allow to configure that.People may also have different error handlers for some code parts, and the only sensible option I see that would allow to configure that is to make it per-file / dir.
set_error_handler()
is also sometimes used to temporary suppress errors (e.g. https://github.com/nikic/FastRoute/blob/2230b97550f2d18c35c0ab1fc7ba32613381cd05/src/Cache/FileCache.php#L79-L95), but those are generally errors emitted by PHP itself and not bytrigger_error()
.So I would propose something like this:
orklah commentedon Jul 18, 2021
That's well thought of, but I feel like it's too complex of a solution for the problem it tries to solve.
If we try to be real here, out of all the projects that will ever use Psalm and out of the projects that have a error handler that will be none on 'default', 'none' or 'always', a few will ever look for the documentation to configurate it just right instead of just suppressing errors
I'll try to propose the basic implementation soon, we can always build on it next if we want to be more thorough
williamdes commentedon Jul 18, 2021
I am not sure a config option is best, could you analyse the implementations of set_error_handler ?
That would avoid having to document all tricky possibilities a human could imagine
weirdan commentedon Jul 18, 2021
That would basically force us to consider all those tricky points I raised above. The problem with
set_error_handler()
is that it's global but is set at runtime, and Psalm is mostly unaware ofinclude
/require
graph, especially when it passes through autoloader.Global state is hard to analyze 🤷
orklah commentedon Jul 27, 2021
This should be basically fixed by the introduction of the config in #6142 unless the beahvior of trigger_error is complex