sleeper_api 1.5.0 → 1.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0fdd2ef6194210448caf049cdd89a37182bcd13205e45ea9543945c172d36fd4
4
- data.tar.gz: 811a0991f5c863956c62c637971571aef98ccd379f9a3bff4b33ad1d28405290
3
+ metadata.gz: c1ac943353dae30f0fd6efa95f54f3287a85e116abd8408e843e980103557e29
4
+ data.tar.gz: 11569ff23125b08872ead08956c3395612a0092cf254a93450997fef069b2f19
5
5
  SHA512:
6
- metadata.gz: 16f575a6d822157d44b7d5aef135626371e0fb03ed8359c70abf82f49bf6d9ae1373ff7a5ee49cbf4c32986593eec23e838b08e70ce5306e29d5fb3df5229be4
7
- data.tar.gz: b7b325b17bfd0c9d921ec16dbaa07fdcf6f277d242732db1f414d11f0c5846664ac300c2fc64f2401a3ef54402c112b8a9e89651f986ba3628a5fdcabc38f394
6
+ metadata.gz: cf5797fea22593f99b428469ea2b99089f9f463f170c86bf7536c9a50398996d6a2edf2f06707b2ae6e3077ccce00d28c1bfe3ee2799943708f65a56090a536d
7
+ data.tar.gz: '08b1850e3dfb474167c1bc8df50700cab7669c7ac77c8d83ad6d757a92968ac345a82c5ecfc05b22b5238351d448782b48d297372acc33448dce0d1f4e9f1618'
data/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## [1.5.1] - 2026-09-25
2
+
3
+ ### Fixed
4
+
5
+ - **A connection that never got an answer now raises `SleeperApi::Error`.**
6
+ Before, only non-2xx responses and timeouts did: no DNS (`SocketError`), a
7
+ refused, reset or unreachable connection (`SystemCallError`), a failed TLS
8
+ handshake (`OpenSSL::SSL::SSLError`) and a socket closed mid-response
9
+ (`EOFError`) escaped `make_request` as themselves. A caller rescuing
10
+ `SleeperApi::Error` for "Sleeper is down" missed the commonest outage of all —
11
+ a laptop waking before its network — and one consumer recorded 196 failed
12
+ imports that its retry policy never saw.
13
+
14
+ The message is `"Could not reach <path>: <original message>"`, naming the host
15
+ for a `WEB_HOST` call. **These are not retried** whatever `retries` is set to:
16
+ they fail at once, and the caller's backoff is the one that can wait long
17
+ enough to matter. `retries` still governs timeouts only.
18
+
1
19
  ## [1.5.0] - 2026-09-25
2
20
 
3
21
  ### Added
data/CLAUDE.md CHANGED
@@ -28,7 +28,7 @@ Four layers, with a deliberate split between HTTP and modeling:
28
28
  - **`SleeperApi`** (`lib/sleeper_api.rb`) — module-level config + memoized global `SleeperApi.client`. `Configuration` validates `timeout` (10–60) and `retries` (0–5), raising `SleeperApi::Error` outside those bounds.
29
29
  - **`Client`** — the only thing that talks HTTP. `include HTTParty` with `base_uri "https://api.sleeper.app"` — **the bare host; the `/v1` lives in each path**. That is deliberate and load-bearing: not every Sleeper endpoint is versioned. `/schedule/{sport}/{season_type}/{season}` is served from the host root, and while `base_uri` carried the version that endpoint was unreachable at any path a caller could pass in. A new endpoint spells out where it lives; do not move the version back into `base_uri` to shorten the paths.
30
30
 
31
- Every call funnels through the private `make_request`, which handles retry-on-timeout, logging, and converts non-2xx into `SleeperApi::Error`. **That error quotes the path**, so the path prefix is part of a public string — v1.2.0 changed it from `"Failed to fetch /user/x: 404"` to `"Failed to fetch /v1/user/x: 404"`. `Client` also owns the 24-hour in-memory player cache.
31
+ Every call funnels through the private `make_request`, which handles retry-on-timeout, logging, and converts non-2xx into `SleeperApi::Error` — and, since 1.5.1, **every connection failure too** (`CONNECTION_ERRORS`: `SocketError`, `SystemCallError`, `OpenSSL::SSL::SSLError`, `EOFError`), unretried, as `"Could not reach <path>: …"`. A consumer can rescue `SleeperApi::Error` alone and see every way a call fails. **That error quotes the path**, so the path prefix is part of a public string — v1.2.0 changed it from `"Failed to fetch /user/x: 404"` to `"Failed to fetch /v1/user/x: 404"`. `Client` also owns the 24-hour in-memory player cache.
32
32
 
33
33
  ⚠️ **There are two Sleeper hosts and v1.4.0 added the second.** `WEB_HOST`
34
34
  (`https://api.sleeper.com`) is the one the web app uses, and it serves
@@ -1,4 +1,5 @@
1
1
  require "httparty"
2
+ require "openssl"
2
3
  require "json"
3
4
  require "erb"
4
5
 
@@ -28,6 +29,12 @@ module SleeperApi
28
29
  # because every other endpoint here lives on `.app`.
29
30
  WEB_HOST = "https://api.sleeper.com".freeze
30
31
 
32
+ # The request never got an answer (1.5.1): no DNS, a refused or reset
33
+ # connection, a failed TLS handshake, a socket closed mid-response. Before,
34
+ # these escaped as themselves, so a caller rescuing SleeperApi::Error for
35
+ # an outage missed the commonest one. Timeouts are handled separately.
36
+ CONNECTION_ERRORS = [SocketError, SystemCallError, OpenSSL::SSL::SSLError, EOFError].freeze
37
+
31
38
  # Not HTTParty's own. Its JSON branch passes `quirks_mode`, which json 3.0
32
39
  # removed, so without this every response raises ArgumentError the moment a
33
40
  # consumer resolves json 3. See JsonParser.
@@ -516,6 +523,11 @@ module SleeperApi
516
523
  @config.logger&.error("Request timed out for #{named} after #{retries} retries")
517
524
  raise SleeperApi::Error, "Request timed out after #{retries} retries"
518
525
  end
526
+ rescue *CONNECTION_ERRORS => e
527
+ # No retry: these fail at once, and the caller's backoff is the one
528
+ # that can wait long enough to matter.
529
+ @config.logger&.error("Could not reach #{named}: #{e.message}")
530
+ raise SleeperApi::Error, "Could not reach #{named}: #{e.message}"
519
531
  end
520
532
  end
521
533
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SleeperApi
4
- VERSION = "1.5.0"
4
+ VERSION = "1.5.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sleeper_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eruity1