Request and response hooks
Section titled “Request and response hooks”onRequest() and onResponse() fire on every attempt, retries included, with a payload that
carries no API key. Hooks run in the order they were registered:
use Fkrzski\SteamApiSdk\Hooks\RequestSending;use Fkrzski\SteamApiSdk\Hooks\ResponseReceived;
$connector ->onRequest(fn (RequestSending $request) => $logger->debug($request->method, $request->query)) ->onResponse(fn (ResponseReceived $response) => $logger->info(sprintf( '%s answered %d in %.3fs on attempt %d', $response->method, $response->status, $response->duration, $response->attempt, )));| Property | Type | Value |
|---|---|---|
method |
string |
ISteamUser/GetPlayerSummaries/v2 |
query |
array<string, mixed> |
the query Steam receives, without key |
attempt |
int |
1, then 2 for the first retry; always 1 under sendAsync() and pool() |
status |
int |
ResponseReceived only: the HTTP status |
duration |
float |
ResponseReceived only: seconds from sending to the answer, onRequest hooks excluded |
A 429 reaches onResponse before the rate limiter turns it into SteamRateLimitException.
A request refused locally, for the quota or a missing key, fires neither hook, and an attempt
Steam never answered fires onRequest alone. middleware() still covers headers, the body
and anything else lower-level, key included.
Failure hook
Section titled “Failure hook”onFailure() fires once per call with the exception the caller is about to get: after the
retries are spent, and as the SDK exception rather than Saloon’s.
$connector->onFailure(fn (Throwable $e) => $logger->error($e->getMessage(), ['exception' => $e]));It fires for a request refused locally, for the quota or a missing key, which neither hook above
sees, and for an exception thrown by another hook or a middleware. Under sendAsync() and
pool() it fires once for every request that fails, before its promise rejects, and so it does
for every chunk that fails in a list over 100 IDs.
Debugging
Section titled “Debugging”debug(), debugRequest() and debugResponse() are Saloon’s. They register on the
connector, so every call after them is dumped. A dump pasted into an issue or a log is where
a key leaks, so the API key comes out masked as key=***:
$connector->debug()->users()->summaries([$id]);Saloon Request (GetPlayerSummariesRequest) -> array:6 [ "connector" => "Fkrzski\SteamApiSdk\SteamConnector" "request" => "Fkrzski\SteamApiSdk\Http\Requests\ISteamUser\GetPlayerSummariesRequest" "method" => "GET" "uri" => "https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=***&steamids=76561197960435530" "headers" => array:1 [ "Host" => "api.steampowered.com" ] "body" => ""]The default dumper is symfony/var-dumper, which the SDK suggests rather than requires:
composer require --dev symfony/var-dumperA callable passed to debugRequest() gets the same masked PSR request, and only that request
is masked. The PendingRequest beside it, the Response in debugResponse(), and
debugRequest() called on a request object rather than the connector all still reach the key.