Class: AtlasRb::Middleware::RaiseOnReadError
- Inherits:
-
Faraday::Middleware
- Object
- Faraday::Middleware
- AtlasRb::Middleware::RaiseOnReadError
- Defined in:
- lib/atlas_rb/middleware/raise_on_read_error.rb
Overview
Raises ResourceError when a read comes back non-2xx, so no read binding can hand an error body back as if it were data.
Why a middleware rather than a guard per binding
Resource.fetch_resource enforces this contract for the typed
single-resource finds, but a binding has to opt in by routing through
it, and the read surface is about thirty methods wide. The failures that
come of forgetting are the ones hardest to attribute: JSON.parse on an
error envelope yields a Hash with no payload key, so the caller
dereferences nil far from the cause; a binding returning a raw body
hands the error text to whatever renders it. Enforcing at the transport
means a binding cannot forget.
Scope: reads only
Keyed on the request method, because SAFE_METHODS is what "a read" means
on the wire. The write path has its own guard
(Resource.write_resource, which names the verb and path in a
NotFoundError), and several write bindings — tombstone,
destroy, complete — deliberately return the raw response so their
caller can read a 422 discriminator Atlas owns as a wire contract.
Raising on those would take that away.
The two POST-shaped reads (Resource.find_many,
Blob.find_many_versions) are out of reach here, so they call
FaradayHelper#read_body — which applies the same mapping —
directly.
Statuses that pass through
404— "absent" is a legitimate answer to a read, so the binding answersnil. That holds for a list read too: "no such container" and "an empty container" mean different things to a UI.410— a tombstone arrives as410 Gonewith its full body, so it is a returnable answer rather than an error envelope.
Ordering
Register this before the typed translators
(RaiseOnStaleResource, RaiseOnResourceError, RaiseOnReadOnlyMode).
Faraday runs on_complete innermost-first, so the handler registered
earliest runs last — which is where this one belongs: a maintenance 503
must stay a ReadOnlyModeError and a refused re-parent must stay
a ForbiddenError, not become a generic ResourceError.
Constant Summary collapse
- SAFE_METHODS =
Request methods this middleware treats as reads.
i[get head].freeze
- PASS_THROUGH =
Read statuses that are answers rather than failures.
[404, 410].freeze
Instance Method Summary collapse
Instance Method Details
#on_complete(env) ⇒ void
This method returns an undefined value.
61 62 63 64 65 66 67 68 69 70 |
# File 'lib/atlas_rb/middleware/raise_on_read_error.rb', line 61 def on_complete(env) return unless SAFE_METHODS.include?(env.method) return if env.status < 400 || PASS_THROUGH.include?(env.status) return if streaming?(env) raise AtlasRb::ResourceError.new( "#{env.method.to_s.upcase} #{env.url&.path} → #{env.status}: #{env.body}", response: env.response ) end |