You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/04_upgrading/upgrading_to_v3.mdx
+13-3Lines changed: 13 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -218,11 +218,15 @@ except RateLimitError:
218
218
...
219
219
```
220
220
221
-
### Behavior change: `.get()` on chained clients now raises on 404
221
+
### Behavior change: 404 on ambiguous endpoints now raises `NotFoundError`
222
222
223
-
`.get()` continues to swallow 404 into `None` for direct, ID-identified fetches like `client.dataset(id).get()` or `client.run(id).get()` — a 404 there unambiguously means the named resource does not exist.
223
+
Direct, ID-identified fetches like `client.dataset(id).get()` or `client.run(id).get()`continue to swallow 404 into `None`— a 404 there unambiguously means the named resource does not exist. Similarly, `.delete()` on an ID-identified client keeps its idempotent behavior (404 is silently swallowed).
224
224
225
-
For chained calls that target a default sub-resource without an ID — `run.dataset()`, `run.key_value_store()`, `run.request_queue()`, `run.log()` — a 404 is ambiguous (it could mean the parent run is missing OR the default sub-resource is missing, and the API body does not disambiguate). These now raise <ApiLinkto="class/NotFoundError">`NotFoundError`</ApiLink> instead of silently returning `None`:
225
+
For calls where a 404 is *ambiguous*, the client now propagates <ApiLinkto="class/NotFoundError">`NotFoundError`</ApiLink> instead of returning `None` / silently succeeding. Three categories of endpoints are affected:
226
+
227
+
1.**Chained calls that target a default sub-resource without an ID** — `run.dataset()`, `run.key_value_store()`, `run.request_queue()`, `run.log()`. A 404 here could mean the parent run is missing OR the default sub-resource is missing, and the API body does not disambiguate. Applies to both `.get()` and `.delete()`.
228
+
2.**`.get()` / `.get_as_bytes()` / `.stream()` on a chained `LogClient`** — e.g. `run.log().get()`. Direct `client.log(build_or_run_id).get()` still returns `None` on 404.
229
+
3.**Singleton sub-resource endpoints fetched via a fixed path** — <ApiLinkto="class/ScheduleClient#get_log">`ScheduleClient.get_log()`</ApiLink>, <ApiLinkto="class/TaskClient#get_input">`TaskClient.get_input()`</ApiLink>, <ApiLinkto="class/DatasetClient#get_statistics">`DatasetClient.get_statistics()`</ApiLink>, <ApiLinkto="class/UserClient#monthly_usage">`UserClient.monthly_usage()`</ApiLink>, <ApiLinkto="class/UserClient#limits">`UserClient.limits()`</ApiLink>, <ApiLinkto="class/WebhookClient#test">`WebhookClient.test()`</ApiLink>. These hit paths like `/schedules/{id}/log` or `/actor-tasks/{id}/input`, so a 404 effectively means the parent is missing. Return types moved from `T | None` to `T`.
226
230
227
231
```python
228
232
from apify_client import ApifyClient
@@ -235,6 +239,12 @@ try:
235
239
except NotFoundError:
236
240
# Previously this returned `None`; now you must handle it explicitly.
# `get_log()` previously returned `None` when the schedule was missing; now it raises.
247
+
schedule_log =None
238
248
```
239
249
240
250
Direct `.get()` also now swallows every 404 regardless of the `error.type` string in the response body (previously only `record-not-found` and `record-or-token-not-found` types were swallowed). If your code needs to distinguish between "resource missing" and "404 with an unexpected type", inspect `.type` on a caught <ApiLinkto="class/NotFoundError">`NotFoundError`</ApiLink> from a non-`.get()` call path.
0 commit comments