Skip to content

feat: add semantic error classes#38

Open
bjeanes wants to merge 3 commits intozammad:masterfrom
bjeanes:feat/exception-classes
Open

feat: add semantic error classes#38
bjeanes wants to merge 3 commits intozammad:masterfrom
bjeanes:feat/exception-classes

Conversation

@bjeanes
Copy link
Copy Markdown

@bjeanes bjeanes commented May 5, 2026

Hello, this is a follow-up to #29 and its speedy fix in c3af2a9.

While that fix removed the JSON::ParserError, it led to a context-less RuntimeError without sufficient information to programmatically discern error reasons. This affects our usage because we do things such as create tickets in background jobs and knowing when to retry (e.g. a 5xx error) vs give up and log an exception more visibly is important.

This PR includes commits to introduce new semantic/contextful exceptions to the failure paths, taking care to:

  • Remain backwards compatible (still RuntimeError, same #message, etc)
  • Minimise lines of code changed in existing paths
  • Provide an interface on new exceptions for callers to sufficiently discern the errors
  • Improve the error message where JSON is unparseable

This PR does not tackle reverting the recent introduction of safe_json_parse because that could be considered a breaking change, though I am in favour of doing so because its remaining usages are only in the success paths, which could lead to a scenario where a 2xx response which somehow included corrupt JSON would not be detectable. In that case, a JSON::ParserError does feel appropriate. Nonetheless, I'll leave the decision to include that change to the maintainers.

This PR is best reviewed commit-by-commit. The first commit introduces the new error classes but preserves all existing specs in an effort to demonstrate backwards compatibility. The second commit changes the specs and introduces tests for the error classes themselves, to support ongoing regression prevention for existing code which may match on the contents of RuntimeError#message.

I hope this code can be merged quickly and I'm more than happy to make revisions as you see fit to get it to an acceptable state.

bjeanes added 3 commits May 5, 2026 11:29
Note: these intentionally do not modify the specs here in order to
ensure this change is as backwards-compatible as I am able to discover.
The errors_spec.rb also validates the interface (inheritance chain of
errors and the derived `message`) to maximise the odds that any existing
consumer which matches on the message of existing `RuntimeError`s will
not experience a breaking change.
If the response is not 2xx in these cases, then the new error handling
code will already re-parse the response body and throw these results
away.

Potentially, it makes sense here to remove `safe_json_parse` and return
to prior behaviour of raising `JSON::ParserError` here, since that
should now only happen on a 2xx which is indeed an _exceptional_
scenario.

However, I am leaving it for now since this was recently released in
a gem version, so could be considered a regression to change again.
We'll see what the Zammad maintainers think...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant