atlas_rb 1.29.0 → 1.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.version +1 -1
- data/CHANGELOG.md +26 -0
- data/Gemfile.lock +1 -1
- data/README.md +31 -9
- data/lib/atlas_rb/blob.rb +78 -19
- data/lib/atlas_rb/errors.rb +55 -0
- data/lib/atlas_rb/faraday_helper.rb +3 -0
- data/lib/atlas_rb/middleware/raise_on_tombstoned.rb +31 -0
- data/lib/atlas_rb/work.rb +9 -0
- data/lib/atlas_rb.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 66d1cdefb1c1d3935fa8cd3721438b8b81b3bd89509317a11beefac39b55c9c9
|
|
4
|
+
data.tar.gz: d8b9bcea27ca0cb9ed3a40b64b31a944c0e6c22ba82aca5f32aa8f293cd16e6a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4bf52d38cef2068881ee863d6f41fcd0d0149eab2714c1cec8d942f0f3f2ef422faeb52b92528579820e88149a5bf9613739e65091f9727df8f1151cdefd543f
|
|
7
|
+
data.tar.gz: dd88d74e36f72f186cbb5a0473b046cef6266b2fb5b45b48b2101db77e643df3d33cefa61048390134962fbbfadf537cb26759d964b1bbd9bf7ee97f84205721
|
data/.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.29.
|
|
1
|
+
1.29.1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.29.1
|
|
4
|
+
|
|
5
|
+
Needs an Atlas that withholds the files beneath a tombstone (0.6.245 or later).
|
|
6
|
+
Against an older Atlas nothing raises, because that Atlas still serves them.
|
|
7
|
+
|
|
8
|
+
### Added — `AtlasRb::TombstonedError`
|
|
9
|
+
|
|
10
|
+
Raised on Atlas's `410` with `error: "tombstoned"`: a file whose Blob, FileSet
|
|
11
|
+
or Work is tombstoned, or a tombstoned Work's file list. A `ResourceError`
|
|
12
|
+
subclass. `tombstoned_resource_id` and `tombstoned_resource_type` name the
|
|
13
|
+
resource whose tombstone applies, and `work_retracted?` is true when that is
|
|
14
|
+
the Work. `Work.assets`, `.file_sets` and `.file_revisions` raise it in place of
|
|
15
|
+
mapping over the error envelope as if it were the list. A `410` carrying the
|
|
16
|
+
resource's own body, as `find` gets, is still returned.
|
|
17
|
+
|
|
18
|
+
### Changed — `Blob.content` and `Blob.version_content` yield only a 2xx body
|
|
19
|
+
|
|
20
|
+
Faraday hands every chunk to `on_data` whatever the status, so an error
|
|
21
|
+
envelope reached the block as file bytes. Now a chunk reaches the block only
|
|
22
|
+
for a `2xx`. A tombstone refusal raises `TombstonedError` before any chunk; any
|
|
23
|
+
other status is returned with no chunk yielded.
|
|
24
|
+
|
|
25
|
+
`Blob.find` documents `tombstoned_in_effect`, `tombstoned_resource_id` and
|
|
26
|
+
`tombstoned_resource_type`, and `Blob.ancestry` documents `file_set_tombstoned`
|
|
27
|
+
and `work_tombstoned`.
|
|
28
|
+
|
|
3
29
|
## 1.29.0
|
|
4
30
|
|
|
5
31
|
Requires an Atlas that serves `GET /works/:id/tombstoned_assets` (0.6.244 or
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -737,11 +737,32 @@ rescue AtlasRb::ResourceError => e
|
|
|
737
737
|
end
|
|
738
738
|
```
|
|
739
739
|
|
|
740
|
-
A `410 Gone`
|
|
741
|
-
tombstone.
|
|
742
|
-
`Blob.version_content`) hand you `{ status:, headers: }`
|
|
743
|
-
|
|
744
|
-
|
|
740
|
+
A `410 Gone` that carries the resource's own body is returned rather than
|
|
741
|
+
raised, the same way `find` returns a tombstone. The two streaming reads
|
|
742
|
+
(`Blob.content`, `Blob.version_content`) hand you `{ status:, headers: }`
|
|
743
|
+
instead of raising. Only a `2xx` body reaches your block, so an error envelope
|
|
744
|
+
never becomes the file; check the status to answer the request.
|
|
745
|
+
|
|
746
|
+
#### A tombstone withholds files
|
|
747
|
+
|
|
748
|
+
Atlas withholds a file when the Blob, its FileSet or its Work is tombstoned,
|
|
749
|
+
and a tombstoned Work's file lists. It answers `410` with `error:
|
|
750
|
+
"tombstoned"`, and the gem raises `AtlasRb::TombstonedError`, a
|
|
751
|
+
`ResourceError`. `Blob.content` raises it before your block sees a chunk, and
|
|
752
|
+
`Work.assets`, `.file_sets` and `.file_revisions` raise it in place of a list.
|
|
753
|
+
Admins and the devolved-admin tier are still served.
|
|
754
|
+
|
|
755
|
+
```ruby
|
|
756
|
+
begin
|
|
757
|
+
AtlasRb::Blob.content(blob_id) { |chunk| response.stream.write(chunk) }
|
|
758
|
+
rescue AtlasRb::TombstonedError => e
|
|
759
|
+
e.tombstoned_resource_type # => "FileSet" (one file removed) or "Work"
|
|
760
|
+
e.work_retracted? # => true when the whole Work is tombstoned
|
|
761
|
+
end
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
To refuse before streaming, read `Blob.find`: `tombstoned_in_effect` and
|
|
765
|
+
`tombstoned_resource_type` say the same thing. Needs Atlas 0.6.245 or later.
|
|
745
766
|
|
|
746
767
|
A **write** raises `AtlasRb::NotFoundError`. The caller asked for a change and
|
|
747
768
|
did not get one, so `nil` would invite the silent failure the read guard was
|
|
@@ -854,8 +875,9 @@ end
|
|
|
854
875
|
|
|
855
876
|
It is not a `ResourceError`, which hosts treat as a refusal of the request.
|
|
856
877
|
|
|
857
|
-
A streaming download (`Blob.content`, `Blob.version_content`)
|
|
858
|
-
this
|
|
878
|
+
A streaming download (`Blob.content`, `Blob.version_content`) does not raise
|
|
879
|
+
this. It returns the `status` and yields no chunk of the error body, so check
|
|
880
|
+
the status.
|
|
859
881
|
|
|
860
882
|
### Atlas's own latency
|
|
861
883
|
|
|
@@ -909,8 +931,8 @@ AtlasRb::Work.assets(work.id)
|
|
|
909
931
|
|
|
910
932
|
# 4. Stream the binary back without buffering it in memory.
|
|
911
933
|
File.open("out.pdf", "wb") do |f|
|
|
912
|
-
|
|
913
|
-
puts headers["content-type"]
|
|
934
|
+
res = AtlasRb::Blob.content(blob.id) { |chunk| f.write(chunk) }
|
|
935
|
+
puts res[:headers]["content-type"]
|
|
914
936
|
end
|
|
915
937
|
|
|
916
938
|
# 5. Look up the acting user and their groups.
|
data/lib/atlas_rb/blob.rb
CHANGED
|
@@ -29,6 +29,12 @@ module AtlasRb
|
|
|
29
29
|
# held bytes — reconciliation compares this against the v1 manifest
|
|
30
30
|
# without re-downloading), and a download URL — or `nil` when the Blob
|
|
31
31
|
# does not exist (`404`).
|
|
32
|
+
#
|
|
33
|
+
# `"tombstoned_in_effect"` is true when the Blob, its FileSet or its Work
|
|
34
|
+
# is tombstoned, and `"tombstoned_resource_type"` says which (`"FileSet"`
|
|
35
|
+
# for a removed file, `"Work"` for a retracted Work). Atlas answers such a
|
|
36
|
+
# Blob `410` with this body, which is returned, so a host can refuse a
|
|
37
|
+
# download before it calls {.content}. Atlas 0.6.245 or later.
|
|
32
38
|
# @raise [AtlasRb::ResourceError] on any non-2xx other than `404` / `410` (e.g. an
|
|
33
39
|
# auth/validation error envelope), carrying Atlas's status + body.
|
|
34
40
|
#
|
|
@@ -58,7 +64,9 @@ module AtlasRb
|
|
|
58
64
|
# header. Falls through to {AtlasRb.config}.default_on_behalf_of when
|
|
59
65
|
# omitted.
|
|
60
66
|
# @return [AtlasRb::Mash, nil] `{ "file_set" => "<noid>", "work" => "<noid>" }`
|
|
61
|
-
# (either value `nil` when unresolvable)
|
|
67
|
+
# (either value `nil` when unresolvable), with `"file_set_tombstoned"` and
|
|
68
|
+
# `"work_tombstoned"` beside them (Atlas 0.6.245 or later; each `nil` with
|
|
69
|
+
# its noid).
|
|
62
70
|
#
|
|
63
71
|
# `nil` when Atlas answers `404` — nothing is there to read, or, with a
|
|
64
72
|
# misconfigured `ATLAS_URL`, the route is not Atlas's at all.
|
|
@@ -114,6 +122,12 @@ module AtlasRb
|
|
|
114
122
|
# @yieldparam chunk [String] the next chunk of binary data.
|
|
115
123
|
# @return [Hash] `{ status: Integer, headers: Faraday::Utils::Headers }` for
|
|
116
124
|
# `GET /files/<id>/content` (`headers` is case-insensitive, hash-like).
|
|
125
|
+
# Only a `2xx` body reaches `chunk_handler`. For any other status no chunk
|
|
126
|
+
# is yielded, so an error envelope can never become the downloaded file;
|
|
127
|
+
# the status is returned for the caller to answer with.
|
|
128
|
+
# @raise [AtlasRb::TombstonedError] when Atlas withholds the bytes because
|
|
129
|
+
# the Blob, its FileSet or its Work is tombstoned (Atlas 0.6.245 or
|
|
130
|
+
# later). Raised before any chunk is yielded.
|
|
117
131
|
#
|
|
118
132
|
# @example Stream the whole body to disk
|
|
119
133
|
# File.open("/tmp/out.pdf", "wb") do |f|
|
|
@@ -126,11 +140,7 @@ module AtlasRb
|
|
|
126
140
|
# res[:status] # => 206
|
|
127
141
|
# res[:headers]["content-range"] # => "bytes 0-1048575/52428800"
|
|
128
142
|
def self.content(id, range: nil, nuid: nil, on_behalf_of: nil, &chunk_handler)
|
|
129
|
-
|
|
130
|
-
req.headers["Range"] = range if range
|
|
131
|
-
req.options.on_data = proc { |chunk, _bytes_received, _env| chunk_handler.call(chunk) }
|
|
132
|
-
end
|
|
133
|
-
{ status: response.status, headers: response.headers }
|
|
143
|
+
stream("#{ROUTE}#{id}/content", range: range, nuid: nuid, on_behalf_of: on_behalf_of, &chunk_handler)
|
|
134
144
|
end
|
|
135
145
|
|
|
136
146
|
# Upload a new Blob attached to a Work.
|
|
@@ -395,28 +405,77 @@ module AtlasRb
|
|
|
395
405
|
# omitted.
|
|
396
406
|
# @yieldparam chunk [String] the next chunk of binary data.
|
|
397
407
|
# @return [Hash] `{ status:, headers: }` — the HTTP status and response
|
|
398
|
-
# headers.
|
|
399
|
-
#
|
|
400
|
-
#
|
|
401
|
-
# writing the chunks to an HTTP response (or a file) must consult it, or
|
|
402
|
-
# an Atlas error page becomes the bytes of the downloaded file. Matches
|
|
403
|
-
# {.content}'s contract.
|
|
408
|
+
# headers. As with {.content}, only a `2xx` body reaches `chunk_handler`,
|
|
409
|
+
# and any other status is returned with no chunk yielded.
|
|
410
|
+
# @raise [AtlasRb::TombstonedError] as {.content} does.
|
|
404
411
|
#
|
|
405
412
|
# @example Download a superseded version to disk
|
|
406
413
|
# File.open("/tmp/old.pdf", "wb") do |f|
|
|
407
414
|
# AtlasRb::Blob.version_content("b-321", "v1") { |chunk| f.write(chunk) }
|
|
408
415
|
# end
|
|
409
416
|
def self.version_content(id, version_id, nuid: nil, on_behalf_of: nil, &chunk_handler)
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
417
|
+
path = "#{ROUTE}#{id}/versions/#{version_id}/content"
|
|
418
|
+
stream(path, nuid: nuid, on_behalf_of: on_behalf_of, &chunk_handler)
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
# The most of an error body kept for the exception. Atlas's envelopes are a
|
|
422
|
+
# few hundred bytes; the cap only bounds a misbehaving proxy.
|
|
423
|
+
ERROR_BODY_LIMIT = 64 * 1024
|
|
424
|
+
|
|
425
|
+
# Faraday hands every chunk to `on_data` whatever the status, and a host
|
|
426
|
+
# streaming to a browser has sent its file headers before the first one
|
|
427
|
+
# arrives. So only a 2xx chunk reaches the caller. Any other body is kept
|
|
428
|
+
# back: a tombstone refusal raises from it, and every other status is
|
|
429
|
+
# returned with no chunk yielded.
|
|
430
|
+
#
|
|
431
|
+
# @api private
|
|
432
|
+
def self.stream(path, nuid:, on_behalf_of:, range: nil, &chunk_handler)
|
|
433
|
+
sink = StreamSink.new(chunk_handler)
|
|
434
|
+
response = connection({}, nuid, on_behalf_of: on_behalf_of).get(path) do |req|
|
|
435
|
+
req.headers["Range"] = range if range
|
|
436
|
+
# A Proc, not a Method: Faraday streams only when on_data is a Proc, and
|
|
437
|
+
# buffers the whole body otherwise.
|
|
438
|
+
req.options.on_data = sink.method(:receive).to_proc
|
|
439
|
+
end
|
|
440
|
+
raise_if_tombstoned(response, sink.error_body)
|
|
441
|
+
{ status: response.status, headers: sink.headers || response.headers }
|
|
442
|
+
end
|
|
443
|
+
private_class_method :stream
|
|
444
|
+
|
|
445
|
+
# @api private
|
|
446
|
+
def self.raise_if_tombstoned(response, body)
|
|
447
|
+
return unless response.status == 410
|
|
448
|
+
|
|
449
|
+
envelope = AtlasRb::TombstonedError.envelope(body)
|
|
450
|
+
raise AtlasRb::TombstonedError.new(envelope, response: response, body: body) if envelope
|
|
451
|
+
end
|
|
452
|
+
private_class_method :raise_if_tombstoned
|
|
453
|
+
|
|
454
|
+
# Routes each streamed chunk by the status Faraday recorded before the first
|
|
455
|
+
# one: a 2xx chunk to the caller, any other into a bounded error body. An
|
|
456
|
+
# env with no status is passed on, because nothing says it is an error.
|
|
457
|
+
#
|
|
458
|
+
# @api private
|
|
459
|
+
class StreamSink
|
|
460
|
+
attr_reader :headers, :error_body
|
|
461
|
+
|
|
462
|
+
def initialize(chunk_handler)
|
|
463
|
+
@chunk_handler = chunk_handler
|
|
464
|
+
@headers = nil
|
|
465
|
+
@error_body = +""
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
def receive(chunk, _bytes_received, env)
|
|
469
|
+
@headers ||= env&.response_headers
|
|
470
|
+
status = env&.status
|
|
471
|
+
if status.nil? || (200..299).cover?(status)
|
|
472
|
+
@chunk_handler.call(chunk)
|
|
473
|
+
elsif @error_body.bytesize < ERROR_BODY_LIMIT
|
|
474
|
+
@error_body << chunk
|
|
416
475
|
end
|
|
417
476
|
end
|
|
418
|
-
{ status: response.status, headers: headers }
|
|
419
477
|
end
|
|
478
|
+
private_constant :StreamSink
|
|
420
479
|
|
|
421
480
|
# Roll a Blob back to a prior version.
|
|
422
481
|
#
|
data/lib/atlas_rb/errors.rb
CHANGED
|
@@ -378,6 +378,61 @@ module AtlasRb
|
|
|
378
378
|
# a caller that only wants "the write failed" can rescue the parent.
|
|
379
379
|
class NotFoundError < ResourceError; end
|
|
380
380
|
|
|
381
|
+
# Raised when Atlas withholds a file, or a Work's file list, because of a
|
|
382
|
+
# tombstone: an HTTP `410` whose body carries `error: "tombstoned"`.
|
|
383
|
+
#
|
|
384
|
+
# A tombstone does not cascade, so the resource that carries it can be an
|
|
385
|
+
# ancestor of the one requested. A Blob is withheld when its FileSet is
|
|
386
|
+
# tombstoned (one file removed) or when its Work is (the whole Work
|
|
387
|
+
# retracted). {#tombstoned_resource_type} tells the two apart, so a host can
|
|
388
|
+
# show "file not found" for the first and its "Removed" page for the second.
|
|
389
|
+
#
|
|
390
|
+
# rescue AtlasRb::TombstonedError => e
|
|
391
|
+
# e.work_retracted? ? render("errors/gone", status: :gone) : head(:not_found)
|
|
392
|
+
#
|
|
393
|
+
# Admins and the devolved-admin tier are still served, so they never see
|
|
394
|
+
# this. A `410` from a single-resource read such as {Work.find} is not this:
|
|
395
|
+
# that one carries the resource's own body, and the read returns it.
|
|
396
|
+
#
|
|
397
|
+
# A subclass of {ResourceError}, so a caller that only wants "the read
|
|
398
|
+
# failed" can rescue the parent. Needs Atlas 0.6.245 or later.
|
|
399
|
+
class TombstonedError < ResourceError
|
|
400
|
+
# The discriminator Atlas renders. An exact-match wire contract.
|
|
401
|
+
CODE = "tombstoned"
|
|
402
|
+
|
|
403
|
+
# @return [String, nil] NOID of the resource whose tombstone applies.
|
|
404
|
+
attr_reader :tombstoned_resource_id
|
|
405
|
+
|
|
406
|
+
# @return [String, nil] its type: `"Work"`, `"FileSet"` or `"Blob"`.
|
|
407
|
+
attr_reader :tombstoned_resource_type
|
|
408
|
+
|
|
409
|
+
# @param envelope [Hash] Atlas's parsed `410` body.
|
|
410
|
+
# @param response [Faraday::Response, nil] the originating response.
|
|
411
|
+
# @param body [String, nil] the raw body, when `response` cannot carry it
|
|
412
|
+
# (a streamed read hands its body to `on_data`, not to the response).
|
|
413
|
+
def initialize(envelope, response: nil, body: nil)
|
|
414
|
+
super(envelope["message"] || "tombstoned", response: response)
|
|
415
|
+
@body = body if body
|
|
416
|
+
@tombstoned_resource_id = envelope["tombstoned_resource_id"]
|
|
417
|
+
@tombstoned_resource_type = envelope["tombstoned_resource_type"]
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
# @return [Boolean] true when the whole Work is tombstoned.
|
|
421
|
+
def work_retracted?
|
|
422
|
+
tombstoned_resource_type == "Work"
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
# @return [Hash, nil] the envelope when `body` is Atlas's tombstone
|
|
426
|
+
# refusal, parsed; `nil` for any other body.
|
|
427
|
+
# @api private
|
|
428
|
+
def self.envelope(body)
|
|
429
|
+
parsed = body.is_a?(Hash) ? body : JSON.parse(body.to_s)
|
|
430
|
+
parsed if parsed.is_a?(Hash) && parsed["error"] == CODE
|
|
431
|
+
rescue JSON::ParserError
|
|
432
|
+
nil
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
|
|
381
436
|
# Raised when Atlas refuses a write because the repository-wide maintenance
|
|
382
437
|
# window is open: an HTTP `503` whose body carries
|
|
383
438
|
# `error: "read_only_mode"`.
|
|
@@ -412,8 +412,11 @@ module AtlasRb
|
|
|
412
412
|
# reason: a dependency outage can answer any request on any shape. It
|
|
413
413
|
# must run before the read guard, or an outage on a read becomes the
|
|
414
414
|
# generic {AtlasRb::ResourceError} a host treats as a refusal.
|
|
415
|
+
# - {Middleware::RaiseOnTombstoned} — a withheld file or file list. It must
|
|
416
|
+
# run before the read guard too, which passes every `410` through.
|
|
415
417
|
def error_middleware(builder, reads:)
|
|
416
418
|
builder.use AtlasRb::Middleware::RaiseOnReadError if reads
|
|
419
|
+
builder.use AtlasRb::Middleware::RaiseOnTombstoned
|
|
417
420
|
builder.use AtlasRb::Middleware::RaiseOnStaleResource
|
|
418
421
|
builder.use AtlasRb::Middleware::RaiseOnResourceError
|
|
419
422
|
builder.use AtlasRb::Middleware::RaiseOnReadOnlyMode
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AtlasRb
|
|
4
|
+
module Middleware
|
|
5
|
+
# Translates Atlas's tombstone refusal into {AtlasRb::TombstonedError}.
|
|
6
|
+
#
|
|
7
|
+
# Atlas answers `410` with `error: "tombstoned"` when it withholds a file's
|
|
8
|
+
# bytes or a tombstoned Work's file list. Without this the refusal reaches
|
|
9
|
+
# {Middleware::RaiseOnReadError}, which lets every `410` through, and a list
|
|
10
|
+
# binding maps over the error envelope as if it were the list.
|
|
11
|
+
#
|
|
12
|
+
# Keyed on the **status + discriminator pair**. A `410` that carries the
|
|
13
|
+
# resource's own body — {AtlasRb::Work.find} on a tombstoned Work — is an
|
|
14
|
+
# answer, not a refusal, and passes through untouched.
|
|
15
|
+
#
|
|
16
|
+
# A streamed read never reaches here with a body: its chunks go to
|
|
17
|
+
# `on_data`. {AtlasRb::Blob.content} checks the status itself.
|
|
18
|
+
class RaiseOnTombstoned < Faraday::Middleware
|
|
19
|
+
# @param env [Faraday::Env] the completed response environment.
|
|
20
|
+
# @raise [AtlasRb::TombstonedError] on a `410` whose body carries
|
|
21
|
+
# `error: "tombstoned"`.
|
|
22
|
+
# @return [void]
|
|
23
|
+
def on_complete(env)
|
|
24
|
+
return unless env.status == 410
|
|
25
|
+
|
|
26
|
+
envelope = AtlasRb::TombstonedError.envelope(env.body)
|
|
27
|
+
raise AtlasRb::TombstonedError.new(envelope, response: env.response) if envelope
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/atlas_rb/work.rb
CHANGED
|
@@ -466,6 +466,9 @@ module AtlasRb
|
|
|
466
466
|
#
|
|
467
467
|
# `nil` when Atlas answers `404` — nothing is there to read, or, with a
|
|
468
468
|
# misconfigured `ATLAS_URL`, the route is not Atlas's at all.
|
|
469
|
+
# @raise [AtlasRb::TombstonedError] when the Work is tombstoned and the
|
|
470
|
+
# caller is below the admin and devolved-admin tiers (Atlas 0.6.245 or
|
|
471
|
+
# later), so a retracted Work's files are never listed.
|
|
469
472
|
# @raise [AtlasRb::ResourceError] on any non-2xx other than `404` / `410`
|
|
470
473
|
# (an auth or validation envelope, a `5xx`, a proxy's `503`), carrying
|
|
471
474
|
# Atlas's status and body so the failure is attributable at the boundary.
|
|
@@ -543,6 +546,9 @@ module AtlasRb
|
|
|
543
546
|
#
|
|
544
547
|
# `nil` when Atlas answers `404` — no such Work, or, with a misconfigured
|
|
545
548
|
# `ATLAS_URL`, the route is not Atlas's at all.
|
|
549
|
+
# @raise [AtlasRb::TombstonedError] when the Work is tombstoned and the
|
|
550
|
+
# caller is below the admin and devolved-admin tiers (Atlas 0.6.245 or
|
|
551
|
+
# later), so a retracted Work's files are never listed.
|
|
546
552
|
# @raise [AtlasRb::ResourceError] on any non-2xx other than `404` / `410`
|
|
547
553
|
# (a `403` for a caller who cannot read the Work, a `5xx`, a proxy's
|
|
548
554
|
# `503`), carrying Atlas's status and body so the failure is attributable
|
|
@@ -625,6 +631,9 @@ module AtlasRb
|
|
|
625
631
|
#
|
|
626
632
|
# `nil` when Atlas answers `404` — nothing is there to read, or, with a
|
|
627
633
|
# misconfigured `ATLAS_URL`, the route is not Atlas's at all.
|
|
634
|
+
# @raise [AtlasRb::TombstonedError] when the Work is tombstoned and the
|
|
635
|
+
# caller is below the admin and devolved-admin tiers (Atlas 0.6.245 or
|
|
636
|
+
# later), so a retracted Work's files are never listed.
|
|
628
637
|
# @raise [AtlasRb::ResourceError] on any non-2xx other than `404` / `410`
|
|
629
638
|
# (an auth or validation envelope, a `5xx`, a proxy's `503`), carrying
|
|
630
639
|
# Atlas's status and body so the failure is attributable at the boundary.
|
data/lib/atlas_rb.rb
CHANGED
|
@@ -22,6 +22,7 @@ require_relative "atlas_rb/middleware/raise_on_stale_resource"
|
|
|
22
22
|
require_relative "atlas_rb/middleware/raise_on_resource_error"
|
|
23
23
|
require_relative "atlas_rb/middleware/raise_on_read_only_mode"
|
|
24
24
|
require_relative "atlas_rb/middleware/raise_on_backend_unavailable"
|
|
25
|
+
require_relative "atlas_rb/middleware/raise_on_tombstoned"
|
|
25
26
|
require_relative "atlas_rb/faraday_helper"
|
|
26
27
|
require_relative "atlas_rb/mash"
|
|
27
28
|
require_relative "atlas_rb/authentication"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: atlas_rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.29.
|
|
4
|
+
version: 1.29.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Cliff
|
|
@@ -177,6 +177,7 @@ files:
|
|
|
177
177
|
- lib/atlas_rb/middleware/raise_on_read_only_mode.rb
|
|
178
178
|
- lib/atlas_rb/middleware/raise_on_resource_error.rb
|
|
179
179
|
- lib/atlas_rb/middleware/raise_on_stale_resource.rb
|
|
180
|
+
- lib/atlas_rb/middleware/raise_on_tombstoned.rb
|
|
180
181
|
- lib/atlas_rb/person.rb
|
|
181
182
|
- lib/atlas_rb/resource.rb
|
|
182
183
|
- lib/atlas_rb/resource_writes.rb
|