mlb 0.10.0 → 0.11.0

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.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/README.md +329 -108
  4. data/lib/mlb/affiliates.rb +28 -0
  5. data/lib/mlb/alumni.rb +30 -0
  6. data/lib/mlb/attendance.rb +28 -0
  7. data/lib/mlb/attendance_record.rb +157 -0
  8. data/lib/mlb/award.rb +89 -11
  9. data/lib/mlb/awards.rb +17 -7
  10. data/lib/mlb/baseball_stat.rb +65 -0
  11. data/lib/mlb/baseball_stats.rb +12 -0
  12. data/lib/mlb/boxscore.rb +81 -0
  13. data/lib/mlb/boxscore_team_stats.rb +210 -0
  14. data/lib/mlb/client.rb +71 -0
  15. data/lib/mlb/coaches.rb +28 -0
  16. data/lib/mlb/code_description_type.rb +45 -0
  17. data/lib/mlb/collection.rb +48 -0
  18. data/lib/mlb/comparable_by_attribute.rb +56 -0
  19. data/lib/mlb/conference.rb +8 -1
  20. data/lib/mlb/conferences.rb +18 -10
  21. data/lib/mlb/connection.rb +130 -7
  22. data/lib/mlb/context_metrics.rb +90 -0
  23. data/lib/mlb/division.rb +24 -6
  24. data/lib/mlb/divisions.rb +24 -18
  25. data/lib/mlb/draft.rb +83 -0
  26. data/lib/mlb/draft_pick.rb +155 -0
  27. data/lib/mlb/error_handler.rb +21 -1
  28. data/lib/mlb/errors/bad_gateway.rb +6 -1
  29. data/lib/mlb/errors/bad_request.rb +1 -0
  30. data/lib/mlb/errors/client_error.rb +1 -0
  31. data/lib/mlb/errors/connection_exception.rb +1 -0
  32. data/lib/mlb/errors/error.rb +1 -0
  33. data/lib/mlb/errors/forbidden.rb +1 -0
  34. data/lib/mlb/errors/gateway_timeout.rb +6 -1
  35. data/lib/mlb/errors/gone.rb +1 -0
  36. data/lib/mlb/errors/http_error.rb +22 -2
  37. data/lib/mlb/errors/internal_server_error.rb +1 -0
  38. data/lib/mlb/errors/network_error.rb +6 -1
  39. data/lib/mlb/errors/not_acceptable.rb +1 -0
  40. data/lib/mlb/errors/not_found.rb +1 -0
  41. data/lib/mlb/errors/payload_too_large.rb +1 -0
  42. data/lib/mlb/errors/retryable.rb +15 -0
  43. data/lib/mlb/errors/server_error.rb +1 -0
  44. data/lib/mlb/errors/service_unavailable.rb +6 -1
  45. data/lib/mlb/errors/too_many_redirects.rb +1 -0
  46. data/lib/mlb/errors/too_many_requests.rb +6 -1
  47. data/lib/mlb/errors/unauthorized.rb +1 -0
  48. data/lib/mlb/errors/unprocessable_entity.rb +1 -0
  49. data/lib/mlb/event_type.rb +61 -0
  50. data/lib/mlb/event_types.rb +12 -0
  51. data/lib/mlb/free_agent.rb +78 -0
  52. data/lib/mlb/free_agents.rb +34 -0
  53. data/lib/mlb/game_changes.rb +87 -0
  54. data/lib/mlb/game_content.rb +251 -0
  55. data/lib/mlb/game_data.rb +155 -0
  56. data/lib/mlb/game_pace.rb +173 -0
  57. data/lib/mlb/game_status.rb +94 -0
  58. data/lib/mlb/game_statuses.rb +12 -0
  59. data/lib/mlb/game_type.rb +98 -0
  60. data/lib/mlb/game_types.rb +12 -0
  61. data/lib/mlb/handedness.rb +28 -10
  62. data/lib/mlb/high_low.rb +121 -0
  63. data/lib/mlb/hit_trajectories.rb +12 -0
  64. data/lib/mlb/hit_trajectory.rb +6 -0
  65. data/lib/mlb/home_run_derby.rb +285 -0
  66. data/lib/mlb/id_description_type.rb +44 -0
  67. data/lib/mlb/inning_score.rb +87 -0
  68. data/lib/mlb/job.rb +58 -0
  69. data/lib/mlb/job_type.rb +39 -0
  70. data/lib/mlb/job_types.rb +12 -0
  71. data/lib/mlb/jobs.rb +87 -0
  72. data/lib/mlb/language.rb +48 -0
  73. data/lib/mlb/languages.rb +12 -0
  74. data/lib/mlb/leader.rb +79 -0
  75. data/lib/mlb/leaders.rb +68 -0
  76. data/lib/mlb/league.rb +95 -14
  77. data/lib/mlb/league_leader_type.rb +21 -0
  78. data/lib/mlb/league_leader_types.rb +12 -0
  79. data/lib/mlb/leagues.rb +24 -18
  80. data/lib/mlb/linescore.rb +342 -0
  81. data/lib/mlb/linescore_teams.rb +89 -0
  82. data/lib/mlb/live_feed.rb +130 -0
  83. data/lib/mlb/logical_event.rb +17 -0
  84. data/lib/mlb/logical_events.rb +12 -0
  85. data/lib/mlb/metric.rb +48 -0
  86. data/lib/mlb/metrics.rb +12 -0
  87. data/lib/mlb/people_changes.rb +34 -0
  88. data/lib/mlb/personnel.rb +28 -0
  89. data/lib/mlb/pitch_code.rb +90 -0
  90. data/lib/mlb/pitch_codes.rb +12 -0
  91. data/lib/mlb/pitch_type.rb +6 -0
  92. data/lib/mlb/pitch_types.rb +12 -0
  93. data/lib/mlb/platform.rb +30 -0
  94. data/lib/mlb/platforms.rb +12 -0
  95. data/lib/mlb/play.rb +300 -0
  96. data/lib/mlb/play_by_play.rb +52 -0
  97. data/lib/mlb/player.rb +182 -0
  98. data/lib/mlb/player_game_stats.rb +350 -0
  99. data/lib/mlb/player_stat.rb +70 -0
  100. data/lib/mlb/players.rb +34 -23
  101. data/lib/mlb/position.rb +65 -0
  102. data/lib/mlb/positions.rb +12 -0
  103. data/lib/mlb/postseason_schedule.rb +41 -0
  104. data/lib/mlb/postseason_series.rb +54 -0
  105. data/lib/mlb/redirect_handler.rb +80 -21
  106. data/lib/mlb/request_builder.rb +33 -2
  107. data/lib/mlb/review_reason.rb +6 -0
  108. data/lib/mlb/review_reasons.rb +12 -0
  109. data/lib/mlb/roster.rb +16 -12
  110. data/lib/mlb/roster_entry.rb +35 -0
  111. data/lib/mlb/roster_type.rb +39 -0
  112. data/lib/mlb/roster_types.rb +12 -0
  113. data/lib/mlb/schedule.rb +33 -0
  114. data/lib/mlb/schedule_date.rb +37 -0
  115. data/lib/mlb/schedule_event_type.rb +25 -0
  116. data/lib/mlb/schedule_event_types.rb +12 -0
  117. data/lib/mlb/scheduled_game.rb +321 -0
  118. data/lib/mlb/season.rb +15 -4
  119. data/lib/mlb/season_date_info.rb +1 -0
  120. data/lib/mlb/seasons.rb +24 -18
  121. data/lib/mlb/single_team_stats.rb +33 -0
  122. data/lib/mlb/situation_code.rb +116 -0
  123. data/lib/mlb/situation_codes.rb +12 -0
  124. data/lib/mlb/skies.rb +12 -0
  125. data/lib/mlb/sky.rb +3 -8
  126. data/lib/mlb/sport.rb +16 -5
  127. data/lib/mlb/sport_players.rb +30 -0
  128. data/lib/mlb/sports.rb +17 -7
  129. data/lib/mlb/standings.rb +47 -0
  130. data/lib/mlb/standings_record.rb +108 -0
  131. data/lib/mlb/standings_type.rb +25 -0
  132. data/lib/mlb/standings_types.rb +12 -0
  133. data/lib/mlb/stat_group.rb +21 -0
  134. data/lib/mlb/stat_groups.rb +12 -0
  135. data/lib/mlb/stat_type.rb +21 -0
  136. data/lib/mlb/stat_types.rb +12 -0
  137. data/lib/mlb/stat_values.rb +158 -0
  138. data/lib/mlb/stats.rb +41 -0
  139. data/lib/mlb/status.rb +14 -0
  140. data/lib/mlb/streaks.rb +184 -0
  141. data/lib/mlb/team.rb +62 -7
  142. data/lib/mlb/team_history.rb +28 -0
  143. data/lib/mlb/team_leader.rb +59 -0
  144. data/lib/mlb/team_leaders.rb +45 -0
  145. data/lib/mlb/team_record.rb +285 -0
  146. data/lib/mlb/team_stat.rb +50 -0
  147. data/lib/mlb/team_stats.rb +52 -0
  148. data/lib/mlb/teams.rb +28 -18
  149. data/lib/mlb/tied_games.rb +32 -0
  150. data/lib/mlb/transaction.rb +125 -0
  151. data/lib/mlb/transactions.rb +11 -6
  152. data/lib/mlb/uniforms.rb +97 -0
  153. data/lib/mlb/utils.rb +45 -0
  154. data/lib/mlb/venue.rb +7 -0
  155. data/lib/mlb/venues.rb +28 -18
  156. data/lib/mlb/version.rb +2 -1
  157. data/lib/mlb/win_probability.rb +64 -0
  158. data/lib/mlb/wind_direction.rb +3 -8
  159. data/lib/mlb/wind_directions.rb +12 -0
  160. data/lib/mlb.rb +61 -0
  161. data/sig/equalizer.rbs +3 -0
  162. data/sig/mlb.rbs +2055 -0
  163. data/sig/shale.rbs +29 -0
  164. metadata +107 -2
data/lib/mlb/division.rb CHANGED
@@ -1,13 +1,22 @@
1
1
  require "equalizer"
2
2
  require "shale"
3
+ require_relative "comparable_by_attribute"
3
4
  require_relative "league"
4
5
  require_relative "sport"
5
6
 
6
7
  module MLB
8
+ # Represents a division (e.g., AL East, NL West)
7
9
  class Division < Shale::Mapper
8
10
  include Comparable
11
+ include ComparableByAttribute
9
12
  include Equalizer.new(:id)
10
13
 
14
+ # Returns the attribute used for sorting
15
+ #
16
+ # @api private
17
+ # @return [Symbol] the attribute used for comparison
18
+ def comparable_attribute = :sort_order
19
+
11
20
  attribute :id, Shale::Type::Integer
12
21
  attribute :name, Shale::Type::String
13
22
  attribute :season, Shale::Type::String
@@ -20,8 +29,21 @@ module MLB
20
29
  attribute :sort_order, Shale::Type::Integer
21
30
  attribute :active, Shale::Type::Boolean
22
31
 
23
- alias_method :active?, :active
24
- alias_method :wildcard?, :has_wildcard
32
+ # Checks if the division is active
33
+ #
34
+ # @api public
35
+ # @example
36
+ # division.active? #=> true
37
+ # @return [Boolean] whether the division is active
38
+ def active? = active
39
+
40
+ # Checks if the division has a wildcard
41
+ #
42
+ # @api public
43
+ # @example
44
+ # division.wildcard? #=> true
45
+ # @return [Boolean] whether the division has a wildcard
46
+ def wildcard? = has_wildcard
25
47
 
26
48
  json do
27
49
  map "id", to: :id
@@ -36,9 +58,5 @@ module MLB
36
58
  map "sortOrder", to: :sort_order
37
59
  map "active", to: :active
38
60
  end
39
-
40
- def <=>(other)
41
- sort_order <=> other.sort_order
42
- end
43
61
  end
44
62
  end
data/lib/mlb/divisions.rb CHANGED
@@ -1,30 +1,36 @@
1
1
  require "shale"
2
- require "uri"
3
- require_relative "sport"
4
2
  require_relative "division"
5
3
 
6
4
  module MLB
5
+ # Collection of divisions from the MLB Stats API
7
6
  class Divisions < Shale::Mapper
8
- attribute :copyright, Shale::Type::String
9
7
  attribute :divisions, Division, collection: true
10
8
 
11
- def self.all(sport: Sport.new(id: 1))
12
- sport_id = sport.respond_to?(:id) ? sport.id : sport
13
- params = {sportId: sport_id}
14
- query_string = URI.encode_www_form(params)
15
- response = CLIENT.get("divisions?#{query_string}")
16
- divisions = from_json(response)
17
- divisions.divisions.sort!
9
+ # Retrieves all divisions
10
+ #
11
+ # @api public
12
+ # @example
13
+ # MLB::Divisions.all
14
+ # @param sport [Integer, Sport] the sport ID or Sport object
15
+ # @return [Array<Division>] list of all divisions
16
+ def self.all(sport: Utils::DEFAULT_SPORT_ID)
17
+ params = {sportId: Utils.extract_id(sport)}
18
+ response = CLIENT.get("divisions?#{Utils.build_query(params)}")
19
+ from_json(response).divisions.sort
18
20
  end
19
21
 
20
- def self.find(division, sport: Sport.new(id: 1))
21
- id = division.respond_to?(:id) ? division.id : division
22
- sport_id = sport.respond_to?(:id) ? sport.id : sport
23
- params = {sportId: sport_id}
24
- query_string = URI.encode_www_form(params)
25
- response = CLIENT.get("divisions/#{id}?#{query_string}")
26
- divisions = from_json(response)
27
- divisions.divisions.sort!.first
22
+ # Finds a division by ID
23
+ #
24
+ # @api public
25
+ # @example
26
+ # MLB::Divisions.find(201)
27
+ # @param division [Integer, Division] the division ID or Division object
28
+ # @param sport [Integer, Sport] the sport ID or Sport object
29
+ # @return [Division, nil] the division if found
30
+ def self.find(division, sport: Utils::DEFAULT_SPORT_ID)
31
+ params = {sportId: Utils.extract_id(sport)}
32
+ response = CLIENT.get("divisions/#{Utils.extract_id(division)}?#{Utils.build_query(params)}")
33
+ from_json(response).divisions.min_by { |d| d.sort_order || 0 }
28
34
  end
29
35
  end
30
36
  end
data/lib/mlb/draft.rb ADDED
@@ -0,0 +1,83 @@
1
+ require "shale"
2
+ require_relative "draft_pick"
3
+
4
+ module MLB
5
+ # Represents a round in the draft
6
+ class DraftRound < Shale::Mapper
7
+ # @!attribute [rw] round
8
+ # Returns the round number
9
+ # @api public
10
+ # @example
11
+ # round.round #=> "1"
12
+ # @return [String] the round
13
+ attribute :round, Shale::Type::String
14
+
15
+ # @!attribute [rw] picks
16
+ # Returns the picks in this round
17
+ # @api public
18
+ # @example
19
+ # round.picks #=> [#<MLB::DraftPick>, ...]
20
+ # @return [Array<DraftPick>] the picks
21
+ attribute :picks, DraftPick, collection: true
22
+
23
+ json do
24
+ map "round", to: :round
25
+ map "picks", to: :picks
26
+ end
27
+ end
28
+
29
+ # Represents a draft year
30
+ class DraftYear < Shale::Mapper
31
+ # @!attribute [rw] draft_year
32
+ # Returns the draft year
33
+ # @api public
34
+ # @example
35
+ # draft.draft_year #=> 2024
36
+ # @return [Integer] the year
37
+ attribute :draft_year, Shale::Type::Integer
38
+
39
+ # @!attribute [rw] rounds
40
+ # Returns the draft rounds
41
+ # @api public
42
+ # @example
43
+ # draft.rounds #=> [#<MLB::DraftRound>, ...]
44
+ # @return [Array<DraftRound>] the rounds
45
+ attribute :rounds, DraftRound, collection: true
46
+
47
+ json do
48
+ map "draftYear", to: :draft_year
49
+ map "rounds", to: :rounds
50
+ end
51
+ end
52
+
53
+ # Provides methods for fetching draft data from the API
54
+ class Draft < Shale::Mapper
55
+ # @!attribute [rw] drafts
56
+ # Returns the draft data
57
+ # @api public
58
+ # @example
59
+ # draft.drafts #=> #<MLB::DraftYear>
60
+ # @return [DraftYear] the draft data
61
+ attribute :drafts, DraftYear
62
+
63
+ json do
64
+ map "drafts", to: :drafts
65
+ end
66
+
67
+ # Retrieves draft picks for a year
68
+ #
69
+ # @api public
70
+ # @example Get draft picks for 2024
71
+ # MLB::Draft.picks(year: 2024)
72
+ # @example Get draft picks for the current year
73
+ # MLB::Draft.picks
74
+ # @param year [Integer, nil] the draft year (defaults to current year)
75
+ # @return [Array<DraftPick>] the draft picks
76
+ def self.picks(year: nil)
77
+ year ||= Utils.current_season
78
+ response = CLIENT.get("draft/#{year}")
79
+ result = from_json(response)
80
+ result.drafts&.rounds&.flat_map(&:picks) || []
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,155 @@
1
+ require "equalizer"
2
+ require "shale"
3
+ require_relative "player"
4
+ require_relative "team"
5
+
6
+ module MLB
7
+ # Represents a school in the draft
8
+ class DraftSchool < Shale::Mapper
9
+ # @!attribute [rw] name
10
+ # Returns the school name
11
+ # @api public
12
+ # @example
13
+ # school.name #=> "Oregon State"
14
+ # @return [String] the school name
15
+ attribute :name, Shale::Type::String
16
+
17
+ # @!attribute [rw] school_class
18
+ # Returns the class level
19
+ # @api public
20
+ # @example
21
+ # school.school_class #=> "4YR JR"
22
+ # @return [String] the class level
23
+ attribute :school_class, Shale::Type::String
24
+
25
+ # @!attribute [rw] city
26
+ # Returns the city
27
+ # @api public
28
+ # @example
29
+ # school.city #=> "Corvallis"
30
+ # @return [String] the city
31
+ attribute :city, Shale::Type::String
32
+
33
+ # @!attribute [rw] state
34
+ # Returns the state
35
+ # @api public
36
+ # @example
37
+ # school.state #=> "OR"
38
+ # @return [String] the state
39
+ attribute :state, Shale::Type::String
40
+
41
+ # @!attribute [rw] country
42
+ # Returns the country
43
+ # @api public
44
+ # @example
45
+ # school.country #=> "USA"
46
+ # @return [String] the country
47
+ attribute :country, Shale::Type::String
48
+
49
+ json do
50
+ map "name", to: :name
51
+ map "schoolClass", to: :school_class
52
+ map "city", to: :city
53
+ map "state", to: :state
54
+ map "country", to: :country
55
+ end
56
+ end
57
+
58
+ # Represents a draft pick
59
+ class DraftPick < Shale::Mapper
60
+ include Equalizer.new(:pick_number, :person)
61
+
62
+ # @!attribute [rw] pick_round
63
+ # Returns the round number
64
+ # @api public
65
+ # @example
66
+ # pick.pick_round #=> "1"
67
+ # @return [String] the round
68
+ attribute :pick_round, Shale::Type::String
69
+
70
+ # @!attribute [rw] pick_number
71
+ # Returns the overall pick number
72
+ # @api public
73
+ # @example
74
+ # pick.pick_number #=> 1
75
+ # @return [Integer] the pick number
76
+ attribute :pick_number, Shale::Type::Integer
77
+
78
+ # @!attribute [rw] round_pick_number
79
+ # Returns the pick number within the round
80
+ # @api public
81
+ # @example
82
+ # pick.round_pick_number #=> 1
83
+ # @return [Integer] the round pick number
84
+ attribute :round_pick_number, Shale::Type::Integer
85
+
86
+ # @!attribute [rw] rank
87
+ # Returns the prospect rank
88
+ # @api public
89
+ # @example
90
+ # pick.rank #=> 1
91
+ # @return [Integer] the rank
92
+ attribute :rank, Shale::Type::Integer
93
+
94
+ # @!attribute [rw] pick_value
95
+ # Returns the pick slot value
96
+ # @api public
97
+ # @example
98
+ # pick.pick_value #=> "10570600"
99
+ # @return [String] the pick value
100
+ attribute :pick_value, Shale::Type::String
101
+
102
+ # @!attribute [rw] signing_bonus
103
+ # Returns the signing bonus
104
+ # @api public
105
+ # @example
106
+ # pick.signing_bonus #=> "8950000"
107
+ # @return [String] the signing bonus
108
+ attribute :signing_bonus, Shale::Type::String
109
+
110
+ # @!attribute [rw] person
111
+ # Returns the drafted player
112
+ # @api public
113
+ # @example
114
+ # pick.person #=> #<MLB::Player>
115
+ # @return [Player] the player
116
+ attribute :person, Player
117
+
118
+ # @!attribute [rw] team
119
+ # Returns the drafting team
120
+ # @api public
121
+ # @example
122
+ # pick.team #=> #<MLB::Team>
123
+ # @return [Team] the team
124
+ attribute :team, Team
125
+
126
+ # @!attribute [rw] school
127
+ # Returns the player's school
128
+ # @api public
129
+ # @example
130
+ # pick.school #=> #<MLB::DraftSchool>
131
+ # @return [DraftSchool] the school
132
+ attribute :school, DraftSchool
133
+
134
+ # @!attribute [rw] blurb
135
+ # Returns the scouting report blurb
136
+ # @api public
137
+ # @example
138
+ # pick.blurb #=> "A native of Sydney..."
139
+ # @return [String] the blurb
140
+ attribute :blurb, Shale::Type::String
141
+
142
+ json do
143
+ map "pickRound", to: :pick_round
144
+ map "pickNumber", to: :pick_number
145
+ map "roundPickNumber", to: :round_pick_number
146
+ map "rank", to: :rank
147
+ map "pickValue", to: :pick_value
148
+ map "signingBonus", to: :signing_bonus
149
+ map "person", to: :person
150
+ map "team", to: :team
151
+ map "school", to: :school
152
+ map "blurb", to: :blurb
153
+ end
154
+ end
155
+ end
@@ -16,7 +16,9 @@ require_relative "errors/unauthorized"
16
16
  require_relative "errors/unprocessable_entity"
17
17
 
18
18
  module MLB
19
+ # Handles HTTP error responses from the MLB Stats API
19
20
  class ErrorHandler
21
+ # Mapping of HTTP status codes to error classes
20
22
  ERROR_MAP = {
21
23
  400 => BadRequest,
22
24
  401 => Unauthorized,
@@ -34,6 +36,14 @@ module MLB
34
36
  504 => GatewayTimeout
35
37
  }.freeze
36
38
 
39
+ # Handles an HTTP response
40
+ #
41
+ # @api public
42
+ # @example
43
+ # handler.handle(response: response)
44
+ # @param response [Net::HTTPResponse] the HTTP response
45
+ # @return [String, nil] the response body if successful
46
+ # @raise [HTTPError] if the response is not successful
37
47
  def handle(response:)
38
48
  raise error(response) unless response.is_a?(Net::HTTPSuccess)
39
49
 
@@ -42,12 +52,22 @@ module MLB
42
52
 
43
53
  private
44
54
 
55
+ # Creates an error from a response
56
+ #
57
+ # @api private
58
+ # @param response [Net::HTTPResponse] the HTTP response
59
+ # @return [HTTPError] the error instance
45
60
  def error(response)
46
61
  error_class(response).new(response:)
47
62
  end
48
63
 
64
+ # Returns the error class for a response
65
+ #
66
+ # @api private
67
+ # @param response [Net::HTTPResponse] the HTTP response
68
+ # @return [Class] the error class
49
69
  def error_class(response)
50
- ERROR_MAP[Integer(response.code)] || HTTPError
70
+ ERROR_MAP.fetch(Integer(response.code), HTTPError)
51
71
  end
52
72
  end
53
73
  end
@@ -1,5 +1,10 @@
1
1
  require_relative "server_error"
2
+ require_relative "retryable"
2
3
 
3
4
  module MLB
4
- class BadGateway < ServerError; end
5
+ # Error raised for HTTP 502 Bad Gateway responses.
6
+ # These errors indicate temporary proxy/gateway issues and are safe to retry.
7
+ class BadGateway < ServerError
8
+ include Retryable
9
+ end
5
10
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "client_error"
2
2
 
3
3
  module MLB
4
+ # Error raised for HTTP 400 Bad Request responses
4
5
  class BadRequest < ClientError; end
5
6
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "http_error"
2
2
 
3
3
  module MLB
4
+ # Error raised for HTTP 4xx client errors
4
5
  class ClientError < HTTPError; end
5
6
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "client_error"
2
2
 
3
3
  module MLB
4
+ # Error raised for connection failures during HTTP requests
4
5
  class ConnectionException < ClientError; end
5
6
  end
@@ -1,3 +1,4 @@
1
1
  module MLB
2
+ # Base error class for all MLB gem errors
2
3
  class Error < StandardError; end
3
4
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "client_error"
2
2
 
3
3
  module MLB
4
+ # Error raised for HTTP 403 Forbidden responses
4
5
  class Forbidden < ClientError; end
5
6
  end
@@ -1,5 +1,10 @@
1
1
  require_relative "server_error"
2
+ require_relative "retryable"
2
3
 
3
4
  module MLB
4
- class GatewayTimeout < ServerError; end
5
+ # Error raised for HTTP 504 Gateway Timeout responses.
6
+ # These errors indicate temporary infrastructure issues and are safe to retry.
7
+ class GatewayTimeout < ServerError
8
+ include Retryable
9
+ end
5
10
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "client_error"
2
2
 
3
3
  module MLB
4
+ # Error raised for HTTP 410 Gone responses
4
5
  class Gone < ClientError; end
5
6
  end
@@ -1,10 +1,30 @@
1
- require "json"
2
1
  require_relative "error"
3
2
 
4
3
  module MLB
4
+ # HTTP error raised when an API request fails
5
5
  class HTTPError < Error
6
- attr_reader :response, :code
6
+ # Returns the HTTP response
7
+ #
8
+ # @api public
9
+ # @example
10
+ # error.response #=> #<Net::HTTPNotFound 404 Not Found>
11
+ # @return [Net::HTTPResponse] the HTTP response
12
+ attr_reader :response
7
13
 
14
+ # Returns the HTTP status code
15
+ #
16
+ # @api public
17
+ # @example
18
+ # error.code #=> "404"
19
+ # @return [String] the HTTP status code
20
+ attr_reader :code
21
+
22
+ # Initializes a new HTTPError instance
23
+ #
24
+ # @api public
25
+ # @example
26
+ # HTTPError.new(response: response)
27
+ # @param response [Net::HTTPResponse] the HTTP response
8
28
  def initialize(response:)
9
29
  super(response.message)
10
30
  @response = response
@@ -1,5 +1,6 @@
1
1
  require_relative "server_error"
2
2
 
3
3
  module MLB
4
+ # Error raised for HTTP 500 Internal Server Error responses
4
5
  class InternalServerError < ServerError; end
5
6
  end
@@ -1,5 +1,10 @@
1
1
  require_relative "error"
2
+ require_relative "retryable"
2
3
 
3
4
  module MLB
4
- class NetworkError < Error; end
5
+ # Error raised when a network connection fails.
6
+ # These errors are typically transient and safe to retry.
7
+ class NetworkError < Error
8
+ include Retryable
9
+ end
5
10
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "client_error"
2
2
 
3
3
  module MLB
4
+ # Error raised for HTTP 406 Not Acceptable responses
4
5
  class NotAcceptable < ClientError; end
5
6
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "client_error"
2
2
 
3
3
  module MLB
4
+ # Error raised for HTTP 404 Not Found responses
4
5
  class NotFound < ClientError; end
5
6
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "client_error"
2
2
 
3
3
  module MLB
4
+ # Error raised for HTTP 413 Payload Too Large responses
4
5
  class PayloadTooLarge < ClientError; end
5
6
  end
@@ -0,0 +1,15 @@
1
+ module MLB
2
+ # Module to mark errors that are safe to retry.
3
+ # Include this in error classes where automatic retry logic is appropriate,
4
+ # such as transient network issues or temporary server unavailability.
5
+ #
6
+ # @api public
7
+ # @example Checking if an error is retryable
8
+ # begin
9
+ # client.get("teams")
10
+ # rescue MLB::Error => e
11
+ # retry if e.is_a?(MLB::Retryable) && attempts < 3
12
+ # raise
13
+ # end
14
+ module Retryable; end
15
+ end
@@ -1,5 +1,6 @@
1
1
  require_relative "http_error"
2
2
 
3
3
  module MLB
4
+ # Error raised for HTTP 5xx server errors
4
5
  class ServerError < HTTPError; end
5
6
  end
@@ -1,5 +1,10 @@
1
1
  require_relative "server_error"
2
+ require_relative "retryable"
2
3
 
3
4
  module MLB
4
- class ServiceUnavailable < ServerError; end
5
+ # Error raised for HTTP 503 Service Unavailable responses.
6
+ # These errors indicate temporary server issues and are safe to retry.
7
+ class ServiceUnavailable < ServerError
8
+ include Retryable
9
+ end
5
10
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "error"
2
2
 
3
3
  module MLB
4
+ # Error raised when too many HTTP redirects are encountered
4
5
  class TooManyRedirects < Error; end
5
6
  end
@@ -1,5 +1,10 @@
1
1
  require_relative "client_error"
2
+ require_relative "retryable"
2
3
 
3
4
  module MLB
4
- class TooManyRequests < ClientError; end
5
+ # Error raised for HTTP 429 Too Many Requests responses.
6
+ # These errors indicate rate limiting and are safe to retry after a delay.
7
+ class TooManyRequests < ClientError
8
+ include Retryable
9
+ end
5
10
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "client_error"
2
2
 
3
3
  module MLB
4
+ # Error raised for HTTP 401 Unauthorized responses
4
5
  class Unauthorized < ClientError; end
5
6
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "client_error"
2
2
 
3
3
  module MLB
4
+ # Error raised for HTTP 422 Unprocessable Entity responses
4
5
  class UnprocessableEntity < ClientError; end
5
6
  end