From 873b7d71d3171d095b1cd32bd32312405459a240 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 09:44:31 +0000 Subject: [PATCH 1/2] Initial plan From 030affaa91999cd856b5fd0b596a281661369f74 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 09:56:19 +0000 Subject: [PATCH 2/2] fix: register withTraceable macro on PendingRequest instead of Factory Agent-Logs-Url: https://github.com/nordkit/wiretap/sessions/04028f73-df69-4258-a44a-59577af29761 Co-authored-by: mjarestad <5223785+mjarestad@users.noreply.github.com> --- CHANGELOG.md | 4 ++- src/Laravel/WiretapServiceProvider.php | 3 +- tests/Feature/WiretapIntegrationTest.php | 38 ++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ead9fe..d7256f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed +- Fixed `Http::withTraceable()` throwing `TypeError` when called directly on the facade by registering the macro on `PendingRequest` instead of `Factory`. + ## [2.3.1] - 2026-04-19 ### Fixed @@ -156,4 +159,3 @@ php artisan migrate [1.2.0]: https://github.com/nordkit/wiretap/compare/v1.1.0...v1.2.0 [1.1.0]: https://github.com/nordkit/wiretap/compare/v1.0.0...v1.1.0 [1.0.0]: https://github.com/nordkit/wiretap/releases/tag/v1.0.0 - diff --git a/src/Laravel/WiretapServiceProvider.php b/src/Laravel/WiretapServiceProvider.php index 0c91a00..2e28815 100644 --- a/src/Laravel/WiretapServiceProvider.php +++ b/src/Laravel/WiretapServiceProvider.php @@ -11,7 +11,6 @@ use Illuminate\Http\Client\PendingRequest; use Illuminate\Routing\Route; use Illuminate\Support\Facades\Event; -use Illuminate\Support\Facades\Http; use Illuminate\Support\ServiceProvider; use Nordkit\Wiretap\Contracts\TraceWriter; use Nordkit\Wiretap\Guzzle\WiretapClient; @@ -119,7 +118,7 @@ public function boot(): void $this->loadMigrationsFrom(__DIR__.'/../../database/migrations'); if ($this->app['config']['wiretap.outbound.laravel_http']) { - Http::macro('withTraceable', function (object $traceable): PendingRequest { + PendingRequest::macro('withTraceable', function (object $traceable): PendingRequest { /** @var PendingRequest $this */ app(TraceableScope::class)->push($traceable); diff --git a/tests/Feature/WiretapIntegrationTest.php b/tests/Feature/WiretapIntegrationTest.php index a8864e1..114d3d7 100644 --- a/tests/Feature/WiretapIntegrationTest.php +++ b/tests/Feature/WiretapIntegrationTest.php @@ -3,11 +3,13 @@ declare(strict_types=1); use GuzzleHttp\Psr7\Request as GuzzlePsrRequest; +use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Http\Client\ConnectionException; use Illuminate\Http\Client\Events\ConnectionFailed; use Illuminate\Http\Client\Request as LaravelHttpRequest; use Illuminate\Support\Facades\Http; +use Illuminate\Support\Facades\Schema; use Nordkit\Wiretap\Laravel\Models\Trace; uses(RefreshDatabase::class); @@ -56,3 +58,39 @@ ->and($log->response_status)->toBeNull() ->and($log->error_message)->toContain('Could not resolve host'); }); + +it('supports calling Http::withTraceable() directly on the facade and stores traceable morph keys', function (): void { + Schema::create('outbound_traceables', function ($table): void { + $table->string('id')->primary(); + $table->timestamps(); + }); + + $model = new class extends Model + { + public $table = 'outbound_traceables'; + + public $incrementing = false; + + protected $keyType = 'string'; + + protected $guarded = []; + }; + + $modelClass = $model::class; + $instance = $modelClass::create(['id' => 'order-1']); + + Http::fake([ + 'github.com/*' => Http::response(['ok' => true], 200), + ]); + + expect(function () use ($instance): void { + Http::withTraceable($instance) + ->post('https://github.com/users', ['name' => 'octocat']); + })->not->toThrow(TypeError::class); + + $trace = Trace::query()->first(); + + expect($trace)->not->toBeNull() + ->and($trace->traceable_type)->toBe($modelClass) + ->and($trace->traceable_id)->toBe('order-1'); +});