Report exceptions from Micropub 500 error paths instead of swallowing them

MicropubController's catch-all handlers returned a generic 500 without
ever calling report(), so failures never reached laravel.log or Flare
(Flare is already wired up via bootstrap/app.php). Widened the final
catch to \Throwable so PHP Errors (e.g. TypeError) get the same
Micropub-shaped error response and are also reported.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Jonny Barnes 2026-09-19 12:22:33 +01:00
commit 6727138f43
Signed by: jonny
SSH key fingerprint: SHA256:CTuSlns5U7qlD9jqHvtnVmfYV3Zwl2Z7WnJ4/dqOaL8
2 changed files with 16 additions and 3 deletions

View file

@ -70,7 +70,9 @@ class MicropubController extends Controller
'error' => 'invalid_request', 'error' => 'invalid_request',
'error_description' => 'No known note with given ID', 'error_description' => 'No known note with given ID',
], 404); ], 404);
} catch (MicropubUnsupportedModelException) { } catch (MicropubUnsupportedModelException $e) {
report($e);
return response()->json([ return response()->json([
'error' => 'invalid', 'error' => 'invalid',
'error_description' => 'This implementation currently only supports the updating of notes', 'error_description' => 'This implementation currently only supports the updating of notes',
@ -80,12 +82,16 @@ class MicropubController extends Controller
'error' => 'invalid_request', 'error' => 'invalid_request',
'error_description' => $e->getMessage(), 'error_description' => $e->getMessage(),
], 400); ], 400);
} catch (MicropubHandlerException) { } catch (MicropubHandlerException $e) {
report($e);
return response()->json([ return response()->json([
'error' => 'unsupported_operation', 'error' => 'unsupported_operation',
'error_description' => 'The request could not be processed by this server', 'error_description' => 'The request could not be processed by this server',
], 500); ], 500);
} catch (\Exception $e) { } catch (\Throwable $e) {
report($e);
return response()->json([ return response()->json([
'error' => 'server_error', 'error' => 'server_error',
'error_description' => 'An error occurred processing the request', 'error_description' => 'An error occurred processing the request',

View file

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Tests\Feature; namespace Tests\Feature;
use App\Exceptions\MicropubHandlerException;
use App\Jobs\SendWebMentions; use App\Jobs\SendWebMentions;
use App\Jobs\SyndicateNoteToBluesky; use App\Jobs\SyndicateNoteToBluesky;
use App\Jobs\SyndicateNoteToMastodon; use App\Jobs\SyndicateNoteToMastodon;
@ -12,6 +13,7 @@ use App\Models\Note;
use App\Models\Place; use App\Models\Place;
use App\Models\SyndicationTarget; use App\Models\SyndicationTarget;
use Faker\Factory; use Faker\Factory;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Queue; use Illuminate\Support\Facades\Queue;
@ -457,6 +459,11 @@ class MicropubControllerTest extends TestCase
#[Test] #[Test]
public function micropub_client_api_request_for_unsupported_post_type_returns_error(): void public function micropub_client_api_request_for_unsupported_post_type_returns_error(): void
{ {
$this->mock(ExceptionHandler::class)
->shouldReceive('report')
->once()
->with(\Mockery::type(MicropubHandlerException::class));
$response = $this->postJson( $response = $this->postJson(
'/api/post', '/api/post',
[ [