Debugging
Relay provides comprehensive debugging tools to help you understand, troubleshoot, and diagnose issues with your API integrations.
Overview
Section titled “Overview”Debugging features in Relay:
- Built-in
debug(),debugRequest(),debugResponse()methods Wiretapfor debugging all requests across connectorsDebuggerfor formatted request/response outputCurlDumperto convert requests to curl commandsHurlDumperto convert requests to Hurl formatLoggingMiddlewarefor request/response logging- Sensitive data redaction
Quick Start
Section titled “Quick Start”Connector-Level Debugging
Section titled “Connector-Level Debugging”// Debug both request and response$connector->debug()->send($request);
// Debug only the request$connector->debugRequest()->send($request);
// Debug only the response$connector->debugResponse()->send($request);
// Debug and terminate after response$connector->debug(die: true)->send($request);Request-Level Debugging
Section titled “Request-Level Debugging”// Debug a specific request (takes precedence over connector)$connector->send($request->debug());
// Debug only this request's response$connector->send($request->debugResponse());Global Debugging
Section titled “Global Debugging”Debug all requests across all connectors:
use Cline\Relay\Observability\Debugging\Wiretap;
// Debug all requests globallyWiretap::enable();
// Stop debuggingWiretap::disable();Custom Debug Handlers
Section titled “Custom Debug Handlers”With Ray
Section titled “With Ray”use Cline\Relay\Core\Request;use Cline\Relay\Core\Response;use Psr\Http\Message\RequestInterface;use Psr\Http\Message\ResponseInterface;
// Debug requests with Ray$connector->debugRequest(function (Request $request, RequestInterface $psrRequest) { ray($psrRequest);});
// Debug responses with Ray$connector->debugResponse(function (Response $response, ResponseInterface $psrResponse) { ray($psrResponse);});Global Custom Handlers
Section titled “Global Custom Handlers”use Cline\Relay\Observability\Debugging\Wiretap;
// Debug all requests with RayWiretap::requests(function (Request $request, RequestInterface $psrRequest) { ray('Request', [ 'method' => $psrRequest->getMethod(), 'uri' => (string) $psrRequest->getUri(), 'headers' => $psrRequest->getHeaders(), ]);});
// Debug all responses with RayWiretap::responses(function (Response $response, ResponseInterface $psrResponse) { ray('Response', [ 'status' => $response->status(), 'body' => $response->json(), 'duration' => $response->duration(), ]);});Debugger Class
Section titled “Debugger Class”Formatting Requests
Section titled “Formatting Requests”use Cline\Relay\Observability\Debugging\Debugger;
$debugger = new Debugger();$request = new CreateUserRequest('john@example.com', 'John Doe');
echo $debugger->formatRequest($request, 'https://api.example.com');Output:
┌─ Request ─────────────────────────────────────│ POST https://api.example.com/users│ Query: page=1&limit=10││ Headers:│ Content-Type: application/json│ Authorization: ***REDACTED***││ Body:│ {│ "email": "john@example.com",│ "name": "John Doe"│ }└───────────────────────────────────────────────Formatting Responses
Section titled “Formatting Responses”$response = $connector->send(new GetUserRequest(1));
echo $debugger->formatResponse($response);Sensitive Data Redaction
Section titled “Sensitive Data Redaction”Debugger automatically redacts sensitive information:
$debugger = new Debugger();
// Default sensitive headers: Authorization, X-API-Key, Cookie, Set-Cookie// Default sensitive body keys: password, secret, token, api_key, access_token, credit_card, cvv, ssnCustom Sensitive Fields
Section titled “Custom Sensitive Fields”$debugger = new Debugger();
$debugger->setSensitiveHeaders([ 'Authorization', 'X-Custom-Secret',]);
$debugger->setSensitiveBodyKeys([ 'password', 'pin', 'social_security',]);CurlDumper
Section titled “CurlDumper”Convert requests to curl commands for testing in terminal.
use Cline\Relay\Observability\Debugging\CurlDumper;
$dumper = new CurlDumper();$curlCommand = $dumper->dump($request, 'https://api.example.com');
echo $curlCommand;// curl -H 'Accept: application/json' 'https://api.example.com/users/1'CurlDumper Options
Section titled “CurlDumper Options”$curlCommand = (new CurlDumper()) ->verbose() ->compressed() ->insecure() ->followRedirects() ->timeout(60) ->dump($request, 'https://api.example.com');HurlDumper
Section titled “HurlDumper”Convert requests to Hurl format for testing.
use Cline\Relay\Observability\Debugging\HurlDumper;
$dumper = new HurlDumper();$hurlContent = $dumper->dump($request, 'https://api.example.com');LoggingMiddleware
Section titled “LoggingMiddleware”Log all requests and responses using PSR-3 loggers.
use Cline\Relay\Features\Middleware\LoggingMiddleware;
class MyConnector extends Connector{ public function middleware(): array { return [ new LoggingMiddleware( logger: $this->logger, logRequestBody: config('app.debug'), logResponseBody: config('app.debug'), ), ]; }}Best Practices
Section titled “Best Practices”- Never log sensitive data in production - Use environment checks
- Use Debugger redaction - Configure sensitive headers and body keys
- Use Wiretap for development - Enable globally in local environment
- Export to curl for manual testing - Debug external issues