airtable-orm 0.2.1 → 0.2.3
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/CHANGELOG.md +23 -0
- data/lib/airtable/orm/http/client.rb +5 -3
- data/lib/airtable/orm/persistence.rb +19 -1
- data/lib/airtable/orm/version.rb +1 -1
- metadata +9 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 628a8ae1f053bb9b1f598608785b9a09062797d152e234d7cd2e2b1a4fefb982
|
|
4
|
+
data.tar.gz: 30813eda1cfb49e6e74418be674490526697264c3d67b6d6f6edd0d3f194c810
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ba0c3abab62e8f8931c6f7ca3f84fe35b343e5341df5ea9652f641c1b8b6d146241be1cd3b554d84232b2d44a1651c475aee2f5abb8580a4b75b2faf9c971806
|
|
7
|
+
data.tar.gz: 3394db605f8b6910d0e41a40c9087ba74daa36b3b5b60d5db65487fa870d4dbc4e0c56c4aed43d5476473e327fc7cf6bd9b6856078578a6809d78b9bc6a5fc49
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.2.3] - 2026-09-24
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Require `faraday >= 2.14.4` (was `~> 2.9`). Older Faraday releases can't parse responses
|
|
8
|
+
once the host resolves json 3.0 (released 2026-09-09): every request raises
|
|
9
|
+
`Faraday::ParsingError: wrong number of arguments`. This affects every earlier airtable-orm
|
|
10
|
+
release, which all allowed any Faraday 2.9+.
|
|
11
|
+
|
|
12
|
+
## [0.2.2] - 2026-09-24
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- `find` raises `RecordNotFound` for a deleted/nonexistent record ID. Airtable answers such a
|
|
17
|
+
GET with `403 INVALID_PERMISSIONS_OR_MODEL_NOT_FOUND`, not 404, so it used to surface as a
|
|
18
|
+
plain `ApiError`. Because a revoked token or lost table permission returns the same 403, `find`
|
|
19
|
+
now disambiguates with one probe of the table (a one-record, no-fields list request): readable
|
|
20
|
+
→ `RecordNotFound`, otherwise the original `ApiError` is re-raised; a `ConnectionError` during
|
|
21
|
+
the probe propagates. The 404 mapping is unchanged. `reload` and `belongs_to` (which reads a
|
|
22
|
+
stale link as `nil`) benefit accordingly.
|
|
23
|
+
- `ApiError` is raised (instead of a `TypeError`) for Airtable's bare string error body such as
|
|
24
|
+
`{"error": "NOT_FOUND"}`, which previously broke the 404 → `RecordNotFound` mapping in `find`.
|
|
25
|
+
|
|
3
26
|
## [0.2.1] - 2026-07-15
|
|
4
27
|
|
|
5
28
|
### Fixed
|
|
@@ -66,11 +66,13 @@ module Airtable
|
|
|
66
66
|
ERB::Util.url_encode(string)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
# Parse an Airtable API error response and raise an ApiError.
|
|
69
|
+
# Parse an Airtable API error response and raise an ApiError. Airtable sends either
|
|
70
|
+
# {"error" => {"type", "message"}} or a bare {"error" => "NOT_FOUND"} (e.g. on 404).
|
|
70
71
|
def self.raise_api_error(status, error)
|
|
71
|
-
|
|
72
|
+
detail = error.is_a?(Hash) ? error["error"] : nil
|
|
73
|
+
type = (detail.is_a?(Hash) ? detail["type"] : detail) || "Communication error"
|
|
72
74
|
msg = case error
|
|
73
|
-
when Hash then
|
|
75
|
+
when Hash then detail.is_a?(Hash) ? detail["message"] : nil
|
|
74
76
|
when String then error
|
|
75
77
|
when NilClass then "invalid or empty response body (not valid JSON)"
|
|
76
78
|
else error.inspect
|
|
@@ -74,7 +74,9 @@ module Airtable
|
|
|
74
74
|
Airtable::ORM::Http::Client.raise_api_error(response.status, parsed_response)
|
|
75
75
|
end
|
|
76
76
|
rescue Airtable::ORM::ApiError => e
|
|
77
|
-
|
|
77
|
+
if e.status == 404 || (missing_record_forbidden?(e) && table_readable?)
|
|
78
|
+
raise Airtable::ORM::RecordNotFound, "Couldn't find record with id=#{id}"
|
|
79
|
+
end
|
|
78
80
|
|
|
79
81
|
raise
|
|
80
82
|
end
|
|
@@ -145,6 +147,22 @@ module Airtable
|
|
|
145
147
|
|
|
146
148
|
private
|
|
147
149
|
|
|
150
|
+
# Airtable answers a GET for a nonexistent (e.g. deleted) record ID with this 403, not
|
|
151
|
+
# 404 — the same response a token without access to the table/base gets.
|
|
152
|
+
def missing_record_forbidden?(error)
|
|
153
|
+
error.status == 403 && error.response.is_a?(Hash) &&
|
|
154
|
+
error.response.dig("error", "type") == "INVALID_PERMISSIONS_OR_MODEL_NOT_FOUND"
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Disambiguates that 403 with one cheap list request (one record, no fields): readable
|
|
158
|
+
# table → the record is gone. Never map the 403 blindly — a revoked token or lost
|
|
159
|
+
# permission would then look like "every record deleted" to the host. A ConnectionError
|
|
160
|
+
# still propagates (retryable, not evidence either way).
|
|
161
|
+
def table_readable?
|
|
162
|
+
response = client.connection.post(api_path("listRecords"), { maxRecords: 1, fields: [] })
|
|
163
|
+
response.success?
|
|
164
|
+
end
|
|
165
|
+
|
|
148
166
|
# Send a single batch PATCH request to Airtable.
|
|
149
167
|
def send_batch_update(batch, result)
|
|
150
168
|
body = {
|
data/lib/airtable/orm/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: airtable-orm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Roman Sklenar
|
|
@@ -35,14 +35,20 @@ dependencies:
|
|
|
35
35
|
requirements:
|
|
36
36
|
- - "~>"
|
|
37
37
|
- !ruby/object:Gem::Version
|
|
38
|
-
version: '2.
|
|
38
|
+
version: '2.14'
|
|
39
|
+
- - ">="
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: 2.14.4
|
|
39
42
|
type: :runtime
|
|
40
43
|
prerelease: false
|
|
41
44
|
version_requirements: !ruby/object:Gem::Requirement
|
|
42
45
|
requirements:
|
|
43
46
|
- - "~>"
|
|
44
47
|
- !ruby/object:Gem::Version
|
|
45
|
-
version: '2.
|
|
48
|
+
version: '2.14'
|
|
49
|
+
- - ">="
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: 2.14.4
|
|
46
52
|
- !ruby/object:Gem::Dependency
|
|
47
53
|
name: faraday-net_http_persistent
|
|
48
54
|
requirement: !ruby/object:Gem::Requirement
|