Follows-up I8520d8cb16 and Ib941c22d6b7ec5f1b9, and adds an internal
setter for use by Setup.php, and for wmf-config:rpc/RunSingleJob.php
which is a use case for setting it after Setup.php but before most
code execution. Interact with a component owner instead of directly
maintaining state and providing a shared API through the Config object.
Change-Id: I5c3d4b11f4e0eb3906ccb5b5fe3979e026459859
Allow callers of MWExceptionHandler::getStructuredExceptionData() and
jsonSerializeException() to explicitly control whether a backtrace is
included in the return value. This avoids the need to rely on the
LogExceptionBacktrace setting in static methods.
Bug: T294739
Change-Id: Ib941c22d6b7ec5f1b984bf5ded90652e42ad7b67
Remove use of two configuration globals. This follows-up to
commit 47adb6d65a (I1a691f01cd82e60) which aimed to access all config
via MediaWikiServices, but that isn't safe during error handling.
These two were only used in the low-level "plain text" and
"basic HTML" error pages, which already can't have any branding,
skinning or localisation; and are not how most exceptions are rendered.
in those edge cases, we can use the name of the software instead of
(trying) to use the name of the site.
== Remove use of $wgSitename ==
In msg() and reportHTML(), remove use of $wgSitename in favour of a
generic fallback matching DefaulSettings.php. This does not affect
the common case of runtime fatals and timeouts, as we're only
changing the fallback after wfMessage() fails in msg(), or when
OutputPage is unavailable, which is typically only if services,
localisation or DB are also down (or not yet loaded). Most exceptions
happen when and after those have initialised fine.
Test case 1:
(Clean state) Edit ViewAction::show() to add `throw new RuntimeException();`
as its first statement, then try to view the main page.
This error page is unchanged. It is skinned, localised, and still uses
the configured sitename in the doc title.
Test case 2:
Edit index.php to call foo() instead of wfIndexMain(),
then try to view the main page. Before, this "minimal HTML" error page
would have a doc title of "Internal error - MyWiki", and now
"Internal error - MediaWiki".
Test case 3:
(Clean state) Edit Message::text() to add `throw new RuntimeException();`,
then try to view the main page. This results in a "plain text" error
page that doesn't even have an HTML doc, and is also unchanged.
== Remove use of $wgMimeType ==
In output(), remove use of $wgMimeType and remove the Content-Type
header that it was used for. This was redundant because the next
statements (reportHTML) already outputs Content-type. In reportHTML,
we sometimes delegate to OutputPage (if safe) and that honours
$wgMimeType already. In other cases, it is handled inline in with a
basic HTML error page, and that branch also sets the Content-Type
header already. In one case (reportOutageHTML) a header was not yet
set. For that one, I've added the missing header call and made it
explicitly text/html.
This is technically a bugfix, because our basic HTML error page is
HTML5, whereas $wgMimeType (which exists to allow enabling XHTML)
can be XHTML which we weren't following. In OutputPage and
Html::htmlHeader that would normally result in outputting `<?xml`.
Test case:
Edit ViewAction::show(), and add `throw new RuntimeException();`
as its first statement, then try to view the main page.
In devtools>network, there is still a proper Content-Type
and charset on the error page document.
Change-Id: I03cfa2b6155fb711582164852e7cab4c325a1b92
Partially reverts 47adb6d65a (I1a691f01cd82e60) as use of service wiring
is not safe in early code like entry points, Setup (incl WebStart/AutoLoader),
and error handling.
Change-Id: I021b8bf34dabe71ec196e89c957238247b1502d0
* Add $wgRequestTimeLimit. If it is non-null, it starts a time limit,
using Excimer with a fallback to set_time_limit().
* Add pretty formatting of timeout exceptions thrown by the library.
Related refactoring.
* Expose the library's critical section feature in MediaWikiServices
* In Setup.php, call warnIfHeadersSent() before sending session headers.
This helped to debug a related issue I had.
* In wfTransactionalTimeLimit() use the new library, and respect the
existing library time limit if it is larger than
$wgTransactionalTimeLimit.
Bug: T269326
Depends-On: I6409ad8a5cba775c27b0d5a79d3300c4dac4c91a
Change-Id: I2e6f6351c451407c06cc7e20932548f7b62e36b6
For other endpoints this was already fixed, as all MWExceptionRenderer
logic checks headers_sent() before outputting headers.
For the MW_API condition, it was calling wfHttpError(), which in
turn unconditionally tried to send headers.
Fix this by removing use of wfHttpError(), and instead re-use the
existing logic for a minimal http error page. Do this by removing
the early condition and instead let if fall into the general
render methods, and then treat MW_API as a non-OutputPage scenario.
Bug: T225657
Change-Id: I38bbf8007078c290a2576ef177b789fab1d2059f
PHP 7.0 makes many error conditions throw instances of the new Error class
which does not extend the known Exception.
The Throwable interface provides a concise and type-safe way of handling
either, e.g. for logging purposes, but HHVM did not support it, requiring
tedious fallback checks.
This commit replaces occurrences of Exception in code paths equally
covered by Throwable, like Exception|Throwable parameter and return types
(also nullable), instanceof guards, duplicated `catch` blocks, as well as
related comments and documentation blocks, with the exception of $previous
parameter descriptions consistent with the manual at
https://www.php.net/manual/en/exception.construct.php
Proper type declarations have been added or reinstated where possible.
Change-Id: I5d3920d3cc66936a350314e2f19c4f6faeffd7c0
Set appropriate headers and flush the output as needed to avoid blocking
the client on post-send updates for the stock apache2 server scenario.
Several cases have bits of header logic to avoid delay:
a) basic GET/POST requests that succeed (e.g. HTTP 2XX)
b) requests that fail with errors (e.g. HTTP 500)
c) If-Modified-Since requests (e.g. HTTP 304)
d) HEAD requests
This last two still block on deferred updates, so schedulePostSendJobs()
does not trigger on them as a form of mitigation. Slow deferred updates
should only trigger on POST anyway (inline and redirect responses are
OK), so this should not be much of a problem.
Deprecate triggerJobs() and implement post-send job runs as a deferred.
This makes it easy to check for the existence of post-send updates by
calling DeferredUpdates::pendingUpdatesCount() after the pre-send stage.
Also, avoid running jobs on requests that had exceptions. Relatedly,
remove $mode option from restInPeace() and doPostOutputShutdown()
Only one caller was using the non-default options.
Bug: T206283
Change-Id: I2dd2b71f1ced0f4ef8b16ff41ffb23bb5b4c7028
HHVM does not support variadic arguments with type hints. This is
mostly not a big problem, because we can just drop the type hint, but
for some reason PHPUnit adds a type hint of "array" when it creates
mocks, so a class with a variadic method can't be mocked (at least in
some cases). As such, I left alone all the classes that seem like
someone might like to mock them, like Title and User. If anyone wants
to mock them in the future, they'll have to switch back to
func_get_args(). Some of the changes are definitely safe, like
functions and test classes.
In most cases, func_get_args() (and/or func_get_arg(), func_num_args() )
were only present because the code was written before we required PHP
5.6, and writing them as variadic functions is strictly superior. In
some cases I left them alone, aside from HHVM compatibility:
* Forwarding all arguments to another function. It's useful to keep
func_get_args() here where we want to keep the list of expected
arguments and their meanings in the function signature line for
documentation purposes, but don't want to copy-paste a long line of
argument names.
* Handling deprecated calling conventions.
* One or two miscellaneous cases where we're basically using the
arguments individually but want to use them as an array as well for
some reason.
Change-Id: I066ec95a7beb7c0665146195a08e7cce1222c788
When a wiki is down, it is not necessarily useful to be able to
search the web. Additionally, there is general consensus that
the hard-coded Google search form should be removed.
Bug: T208871
Change-Id: I5bcae848de1144d4fc1116c475b2e2ab1ccc3f7d
These methods aren't identical, so consolidation isn't
immediately obvious, and creating dependencies is problematic
in error handling code given there is a lot of pressure on this
code to not by itself cause additional errors.
This means that maybe it's best to keep these inlined without
duplication, but at the very least we then need to remember
to keep these in sync. This duplication has been around for
a while now, but documentation can never come too late...
Change-Id: I60160f61c13c8e115d839acce222f110e30bc2f2
Previously an ugly {{SITENAME}} would show up for exceptions
that happened in the middle of processing a message
Change-Id: I4e3b675673dc3b74f89e4325f6a0a8b44162f478
Clarify and simplify exception output by deprecating
$wgShowSQLErrors and wgShowDBErrorBacktrace.
$wgShowExceptionDetails will now control most related output.
$wgShowHostnames will now solely control output of
MWExceptionRenderer::reportOutageHTML.
Bug: T165768
Change-Id: Idead2c11c499463dfa6293c3d4b33be3bde92e1a
This message contains the request url, which is semi-user controlled.
Most browsers percent escape < and > so its probably not exploitable
(curl is an exception here), but nonetheless its not good.
Bug: T178451
Change-Id: I19358471ddf1b28377aad8e0fb54797c817bb6f6
Also add a period at the end of the sentence.
This changes the HTML comment from
<!-- Set $wgShowExceptionDetails = true; at the bottom
of LocalSettings.php to show detailed debugging
information
-->
to
<!-- Set $wgShowExceptionDetails = true; at the bottom
of LocalSettings.php to show detailed debugging
information. -->
This is a follow-up to 842b7a1769 (T162315).
Change-Id: I45ff4f856ad1c0dc72066fce7771077ff4663785
Skip deprecation period because it is very unlikely that anyone used this:
it does not appear anywhere on gerrit/git, no nontrivial google hits,
the documentation has been flat out wrong for 9 years and no one
noticed it, and the whole feature is fairly useless as you need to declare
it separately for every single exception class you expect.
Change-Id: I85844a238d3135d05eeba10331149624b04bafe2
* Actually use MWExceptionRenderer::AS_RAW. Use this after
an error is thrown while trying to pretty render the original
error. This is how this case was originally handled before.
* Do not show the google form or file cache in CLI mode.
Change-Id: I130499753efbf8b4d6d254ea36bacb2473952c1b