@@ -31,6 +31,7 @@ public static function handleHttpError(ResponseInterface $response): void
3131 match ($ statusCode ) {
3232 401 => throw new AuthenticationException ($ errorMessage ),
3333 404 => throw new NotFoundException ($ errorMessage ),
34+ 429 => throw new RateLimitExceededException (self ::extractRetryAfter ($ response )),
3435 503 => throw new ServiceUnavailableException ($ errorMessage ),
3536 default => throw new RuntimeException (\sprintf ('HTTP %d: %s ' , $ statusCode , $ errorMessage )),
3637 };
@@ -44,7 +45,7 @@ private static function extractErrorMessage(ResponseInterface $response): string
4445 return \sprintf ('HTTP %d error ' , $ response ->getStatusCode ());
4546 }
4647
47- $ data = json_decode ($ content , true , 512 , \ JSON_THROW_ON_ERROR );
48+ $ data = json_decode ($ content , true );
4849
4950 if (!\is_array ($ data )) {
5051 return $ content ;
@@ -60,4 +61,47 @@ private static function extractErrorMessage(ResponseInterface $response): string
6061
6162 return $ data ['message ' ] ?? $ data ['detail ' ] ?? $ content ;
6263 }
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+ }
63107}
0 commit comments