@@ -31,6 +31,7 @@ public static function handleHttpError(ResponseInterface $response): void
31
31
match ($ statusCode ) {
32
32
401 => throw new AuthenticationException ($ errorMessage ),
33
33
404 => throw new NotFoundException ($ errorMessage ),
34
+ 429 => throw new RateLimitExceededException (self ::extractRetryAfter ($ response )),
34
35
503 => throw new ServiceUnavailableException ($ errorMessage ),
35
36
default => throw new RuntimeException (\sprintf ('HTTP %d: %s ' , $ statusCode , $ errorMessage )),
36
37
};
@@ -44,7 +45,7 @@ private static function extractErrorMessage(ResponseInterface $response): string
44
45
return \sprintf ('HTTP %d error ' , $ response ->getStatusCode ());
45
46
}
46
47
47
- $ data = json_decode ($ content , true , 512 , \ JSON_THROW_ON_ERROR );
48
+ $ data = json_decode ($ content , true );
48
49
49
50
if (!\is_array ($ data )) {
50
51
return $ content ;
@@ -60,4 +61,47 @@ private static function extractErrorMessage(ResponseInterface $response): string
60
61
61
62
return $ data ['message ' ] ?? $ data ['detail ' ] ?? $ content ;
62
63
}
64
+
65
+ private static function extractRetryAfter (ResponseInterface $ response ): ?float
66
+ {
67
+ $ headers = $ response ->getHeaders (false );
68
+
69
+ if (isset ($ headers ['retry-after ' ][0 ])) {
70
+ return (float ) $ headers ['retry-after ' ][0 ];
71
+ }
72
+
73
+ if (isset ($ headers ['x-ratelimit-reset-requests ' ][0 ])) {
74
+ return self ::parseResetTime ($ headers ['x-ratelimit-reset-requests ' ][0 ]);
75
+ }
76
+
77
+ if (isset ($ headers ['x-ratelimit-reset-tokens ' ][0 ])) {
78
+ return self ::parseResetTime ($ headers ['x-ratelimit-reset-tokens ' ][0 ]);
79
+ }
80
+
81
+ return null ;
82
+ }
83
+
84
+ private static function parseResetTime (string $ resetTime ): ?float
85
+ {
86
+ if (is_numeric ($ resetTime )) {
87
+ return (float ) $ resetTime ;
88
+ }
89
+
90
+ if (preg_match ('/^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/ ' , $ resetTime , $ matches )) {
91
+ $ hours = (int ) ($ matches [1 ] ?? 0 );
92
+ $ minutes = (int ) ($ matches [2 ] ?? 0 );
93
+ $ seconds = (int ) ($ matches [3 ] ?? 0 );
94
+
95
+ return (float ) ($ hours * 3600 + $ minutes * 60 + $ seconds );
96
+ }
97
+
98
+ $ timestamp = strtotime ($ resetTime );
99
+ if (false === $ timestamp ) {
100
+ return null ;
101
+ }
102
+
103
+ $ diff = $ timestamp - time ();
104
+
105
+ return $ diff > 0 ? (float ) $ diff : null ;
106
+ }
63
107
}
0 commit comments