rfc:json_throw_on_error

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
rfc:json_throw_on_error [2017/09/10 01:18]
ajf
rfc:json_throw_on_error [2017/10/22 18:44] (current)
ajf implement
Line 1: Line 1:
 ====== PHP RFC: JSON_THROW_ON_ERROR ====== ====== PHP RFC: JSON_THROW_ON_ERROR ======
-  * Version: 1.0+  * Version: 1.0.2
   * Date: 2017-09-10   * Date: 2017-09-10
   * Author: Andrea Faulds   * Author: Andrea Faulds
-  * Status: Under Discussion or Accepted or Declined)+  * Status: Implemented (PHP 7.3)
   * First Published at: http://wiki.php.net/rfc/json_throw_on_error   * First Published at: http://wiki.php.net/rfc/json_throw_on_error
  
Line 9: Line 9:
 PHP has two functions for dealing with JSON, <php>json_decode()</php> and <php>json_encode()</php>. Unfortunately, both have suboptimal error handling. <php>json_decode()</php> returns <php>null</php> upon erroring, but <php>null</php> is also a possible valid result (if decoding the JSON ''"null"''). It is only possible to know if an error occurred by calling <php>json_last_error()</php> or <php>json_last_error_msg()</php>, which return the global error state in machine-readable and human-readable forms respectively. <php>json_encode()</php> also uses this system, but at least does have a clear error return value. But both functions also do not halt program execution by default on error, or even throw a warning. PHP has two functions for dealing with JSON, <php>json_decode()</php> and <php>json_encode()</php>. Unfortunately, both have suboptimal error handling. <php>json_decode()</php> returns <php>null</php> upon erroring, but <php>null</php> is also a possible valid result (if decoding the JSON ''"null"''). It is only possible to know if an error occurred by calling <php>json_last_error()</php> or <php>json_last_error_msg()</php>, which return the global error state in machine-readable and human-readable forms respectively. <php>json_encode()</php> also uses this system, but at least does have a clear error return value. But both functions also do not halt program execution by default on error, or even throw a warning.
  
-This situation is suboptimal, and throwing exceptions would be cleaner: there would be no confusion between error values and correct results, no (possibly outdated) global state, no program execution after the error is thrown unless explicitly handled, and error messages would be neatly traceable to their source. However, to immediately change the default behaviour of these functions would be a backwards-compatibility issue.+This situation is suboptimal, and throwing exceptions would be cleaner: there would be no confusion between error values and correct results, no (possibly outdated) global state, no program execution after the error is thrown unless explicitly handled, and error messages would be neatly traceable to their source. However, to immediately change the default behaviour of these functions to throw would be a significant backwards-compatibility issue, and producing a notice or warning is not ideal for predictable, routine errors that are not bugs or poor code style (as JSON decoding may be when given user input, for instance).
  
 ===== Proposal ===== ===== Proposal =====
-This RFC instead proposes adding a new option flag value for <php>json_decode()</php> and <php>json_encode()</php>, <php>JSON_THROW_ON_ERROR</php>. When passed this flag, the error behaviour of these functions is changed. Instead of setting the global error state, they throw a <php>JsonException</php> with the message and code set to whatever <php>json_last_error()</php> and <php>json_last_error_msg()</php> would otherwise be respectively.+This RFC instead proposes adding a new option flag value for <php>json_decode()</php> and <php>json_encode()</php>, <php>JSON_THROW_ON_ERROR</php>. When passed this flag, the error behaviour of these functions is changed. The global error state is left untouched, and if an error occurs that would otherwise set itthese functions instead throw a <php>JsonException</php> with the message and code set to whatever <php>json_last_error()</php> and <php>json_last_error_msg()</php> would otherwise be respectively. <php>JSON_PARTIAL_OUTPUT_ON_ERROR</php> would override and disable <php>JSON_THROW_ON_ERROR</php>, so that generic wrapper functions that always pass the <php>JSON_PARTIAL_OUTPUT_ON_ERROR</php> flag continue to support <php>JSON_PARTIAL_OUTPUT_ON_ERROR</php>.
  
 <php>JsonException</php> would be a new class that subclasses <php>Exception</php>. <php>JsonException</php> would be a new class that subclasses <php>Exception</php>.
  
-At the present time, there would be no change to the default error behaviour. It would be worthwhile considering whether to eventually deprecate not using <php>JSON_THROW_ON_ERROR</php>, however.+Note that when given an invalid depth parameter, <php>json_decode()</php> outputs a warning and returns NULL. This behaviour is unaffected by <php>JSON_THROW_ON_ERROR</php> because it does not affect the global error state at present, has no corresponding error code to throw an exception with, and is not dependent on user input. Similarly, parameter parsing errors continue to produce warnings (when not in strict mode) because their error behaviour cannot be conditioned on the value of a parameter being parsed. Both can be caught by a user error handler that converts errors to exceptions. 
 + 
 +At the present time, there would be no change to the default error behaviour. It would be worthwhile considering whether to eventually slowly deprecate not using <php>JSON_THROW_ON_ERROR</php> and then change the default behaviourbut this RFC does not do this.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
Line 40: Line 42:
 As mentioned earlier, it may be desirable to deprecate the default behaviour eventually. As mentioned earlier, it may be desirable to deprecate the default behaviour eventually.
  
-===== Proposed Voting Choices ===== +===== Vote ===== 
-This is not a language change, merely a small addition to the JSON extension, so it only technically requires a 50%+1 majority.+This is not a language change, merely a small addition to the JSON extension, so it only technically requires a 50%+1 majority. However, it's a 2/3 vote. It is a simple Yes/No vote on whether to accept this RFC and merge the patch.
  
-It would be a simple Yes/No vote on whether to accept this RFC and merge the patch.+Voting started 2017-09-25 and ended 2017-10-05. 
 + 
 +<doodle title="Accept and merge JSON_THROW_ON_ERROR for PHP 7.3?" auth="ajf" voteType="single" closed="true"> 
 +   * Yes 
 +   * No 
 +</doodle>
  
 ===== Patches and Tests ===== ===== Patches and Tests =====
Line 49: Line 56:
  
 ===== Implementation ===== ===== Implementation =====
 +
 +Merged in PHP 7.3: https://github.com/php/php-src/commit/e823770515bd0530bd3c09ea273c720b4df33734
 +
 After the project is implemented, this section should contain  After the project is implemented, this section should contain 
-  - the version(s) it was merged to 
-  - a link to the git commit(s) 
   - a link to the PHP manual entry for the feature   - a link to the PHP manual entry for the feature
-  - a link to the language specification section (if any) 
  
 ===== References ===== ===== References =====
Line 63: Line 70:
 ===== Rejected Features ===== ===== Rejected Features =====
 Keep this updated with features that were discussed on the mail lists. Keep this updated with features that were discussed on the mail lists.
 +
 +===== Changelog =====
 +
 +  * v1.0.2 - change behaviour to leave global error flag untouched, rather than clearing it; note depth, param-parsing errors
 +  * v1.0.1 - cover details of the patch not previously mentioned
 +  * v1.0 - initial version
rfc/json_throw_on_error.1505006312.txt.gz · Last modified: 2017/09/22 13:28 (external edit)