🥅 Only print parser debug for unhandled errors#600
Merged
Conversation
Previously, `ResponseParser#parse_error` would _immediately_ print its debug information, prior to raising. This commit changes `#parse_error` to simply _raise_ the exception. The parse error debug detailed_message will be printed by `#parse` (which is currently the only entrypoint into the parser). Motivation: For years, I've used custom ResponseParser subclasses which rescue specific parse errors and can attempt to parse using a fallback approach (usually backtracking first). And I'd like to merge some some of this code back into in the core ResponseParser. That means that `parse_error` can be recoverable inside the parser. Without this change, parse error recovery would either print spurious parse errors, or require temporarily disabling debug. Both approaches add significant difficulty to debugging. Unfortunately, `throw`/`catch` cannot be used for this purpose, because the parse error's `#backtrace` and `#cause` are essential for debugging parse errors, _especially_ when working with backtracking.
f43eb86 to
feefc51
Compare
Base automatically changed from
response_parse_error-detailed_message
to
master
February 9, 2026 21:15
nevans
added a commit
that referenced
this pull request
Feb 10, 2026
`resp-text` is defined as: ```abnf resp-text = ["[" resp-text-code "]" SP] text ; RFC3501 resp-text = ["[" resp-text-code "]" SP] [text] ; RFC9051 ``` And our even more lenient interpretation (which incorporates RFC9051 errata), is this: ```abnf resp-text = ["[" resp-text-code "]" [SP [text]] / [text] ``` And, although the `resp-text-code` grammar is elaborate, the final alternative is a superset of every other alternative (in both RFCs): ```abnf resp-text-code /= atom [SP 1*<any TEXT-CHAR except "]">] ``` Notice that `text` is a superset of `atom`, `SP`, `"["`, `"]"`, and every other allowed character in `resp-text-code`. So, even if `resp-text-code` fails, `resp-text` may still succeed by parsing everything as `text`. However, (prior to this commit) the parser commits to `resp-text-code` as soon as `"["` is encountered at the beginning of `resp-text`. If what follows is not `resp-text-code`, maybe it doesn't begin with an `atom` or it doesn't have a closing `"]"`, then we fail to parse `resp-text` correctly. Fixing this requires either looking further ahead more than a single token or backtracking when `resp-text-code` fails to parse. In this case, I think backtracking is the best approach. We don't need to worry about backtracking taking exponential time, because the fallback (`text`) is exceptionally simple (does not call any other productions), will parse all the way up to the next CRLF, and so nothing backtrackable can be nested. This uses `ResponseParser#current_state` that was added for #599 and relies on #600 to ensure that debug error messages are not printed when backtracking. Fixes #597.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Previously,
ResponseParser#parse_errorwould immediately print its debug information, prior to raising. This commit changes#parse_errorto simply raise the exception. The parse error debug detailed_message will be printed by#parse(which is currently the only entrypoint into the parser).Motivation
For years, I've used custom ResponseParser subclasses which rescue specific parse errors and can attempt to parse using a fallback approach (usually backtracking first). And I'd like to merge some some of this code back into in the core ResponseParser. That means that
parse_errorcan be recoverable inside the parser.Without this change, parse error recovery would either print spurious parse errors, or require temporarily disabling debug. Both approaches add significant difficulty to debugging.
Unfortunately,
throw/catchcannot easily be used for this purpose, because the parse error's#backtraceand#causeare essential for debugging parse errors, especially when working with backtracking.