There are many different situations in which a block error notice might be shown to a user, and the message is often different depending on the situation.
Error messages also differ depending on the features of the block. A few examples:
* The desktop editing message differs according to the type of block (`DatabaseBlock`, `SystemBlock`, etc), whether the block is an autoblock, and whether it is partial/sitewide
* The `Special:EmailUser` message differs according to whether the block is partial/sitewide
* The `Special:CreateAccount` message differs according to whether the block is against an IP range or not
The message customization is //ad hoc//, and can be improved. In addition, some messages do not make sense and need fixing (e.g. T227110, T226990, T212326#5270394).
**How block errors are made**
Block errors are reported using a message key and formatted block details to pass in as message parameters.
`AbstractBlock::getBlockErrorParams()` returns an array of parameters, and `AbstractBlock::getPermissionsError()` adds an error message key to the array. The different block types use different message keys, which pass in different parameters. Additionally, `ApiBlockInfoTrait::getDetails()` returns an array of block error parameters, independently of `AbstractBlock::getBlockErrorParams()`. (These two methods each return a different set of parameters, so different information about the block is available in different situations.)
The information for the error message is built in the following different ways:
1. Call `AbstractBlock::getPermissionsError()`, or throw a `UserBlockedError`, which calls `AbstractBlock::getPermissionsError()` (example: desktop editing)
2. Call `AbstractBlock::getBlockErrorParams()` directly, and add a custom message key to the array (example: emailing)
3. Get block error params from `ApiBlockInfoTrait::getBlockDetails()` and create a custom message (example: mobile editing)
4. Get information about the block directly (e.g. by calling `$block->getId()`, `$block->getReason()`, etc) and create a custom message (example: account creation)
**Making block errors more consistent**
Thinking about long-term stability, it could be helpful if block message creation were more centralized. However, we should be careful to allow for flexibility and customization where appropriate.
Some ideas:
* We could define a superset of details that can describe any block, and make sure that `AbstractBlock::getErrorParams()` and `ApiBlockInfoTrait::getBlockDetails()` get these from the same place. Messages could then choose which of these details to use.
* We could try to re-route places where errors are built using (2) and (4) to use (1) and (3). E.g. we could restructure the block messages so that they always show the same details for a particular type of block (`DatabaseBlock`, `SystemBlock`, etc) - or no details at all where appropriate - and add a custom prefix (e.g. "You have been blocked from using email", "You have been blocked from creating an account", etc).
* We could make some kind of formatting layer between the block object and the error. We could move `AbstractBlock::getErrorParams()` and `AbstractBlock::getPermissionsError()` to this layer, thus moving the context/language dependency out of blocks (and potentially addressing other language-related problems such as T227007).
---
**Plan**
* Create a block error formatting service and move the logic for formatting error params and building the final error message array to this service
* A method on the block classes returns a set of normalised, unformatted error params (e.g. as an associative array/object); the params should be consistent with a predefined interface
* The service accepts a block object and some information about the context (perhaps a message key?) and builds an error message array based on these