From 01e0b41273b4cd3b3ca284919115f9c6cef4f0bf Mon Sep 17 00:00:00 2001 From: Ben Peachey Date: Mon, 7 Sep 2026 10:57:45 +0200 Subject: [PATCH 1/2] Add error handling for mailing failure. --- lib/Mailer.php | 8 +++++++- lib/Routes/Account.php | 19 ++++++++++++++++--- tests/phpunit/MailerTest.php | 20 +++++++++++++++++++- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/lib/Mailer.php b/lib/Mailer.php index aae8a83..b59fcc5 100644 --- a/lib/Mailer.php +++ b/lib/Mailer.php @@ -88,7 +88,13 @@ public static function sendVerify($data) $mailer->Body = $mailHtmlBody; $mailer->AltBody = $mailPlainBody; - return $mailer->send(); + $result = $mailer->send(); + + if ($result === false || $mailer->isError()) { + throw new \Exception($mailer->ErrorInfo); + } + + return $result; } public static function sendResetPassword($data) diff --git a/lib/Routes/Account.php b/lib/Routes/Account.php index d9fb789..ba9dc41 100644 --- a/lib/Routes/Account.php +++ b/lib/Routes/Account.php @@ -52,10 +52,23 @@ public static function respondToAccountVerify() ]; $verifyToken = User::saveVerifyToken('verify', $verifyData); - Mailer::sendVerify($verifyToken); - $responseData = "OK"; - header("HTTP/1.1 201 Created"); + try { + Mailer::sendVerify($verifyToken); + + $responseCode = 201; + $responseData = "OK"; + } catch (\Throwable $e) { + error_log('Could not send verification email (' . get_class($e) . '):' . $e->getMessage()); + + $responseCode = 502; + $responseData = [ + 'title' => 'Mail could not be sent', + 'errors' => [['detail' => 'Failed to send verification email']] + ]; + } + + http_response_code($responseCode); header("Content-type: application/json"); echo json_encode($responseData, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR); } diff --git a/tests/phpunit/MailerTest.php b/tests/phpunit/MailerTest.php index 222f592..7fb5cc3 100644 --- a/tests/phpunit/MailerTest.php +++ b/tests/phpunit/MailerTest.php @@ -25,12 +25,18 @@ class MailerMock public $Body; public $AltBody; public $addresses = []; + public $ErrorInfo = ''; public function addAddress($address) { $this->addresses[] = $address; } + public function isError() + { + return $this->ErrorInfo !== ''; + } + public function send() { return true; @@ -77,7 +83,7 @@ public function testAccountCreated() $this->assertEquals("Welcome to Solid!", $doc->getElementsByTagName("title")[0]->textContent); // If this works, I'm assuming it is valid HTML. } - public function testVerify() + public function testVerifySucces() { Mailer::$mailer = new MailerMock(); Mailer::sendVerify([ @@ -99,6 +105,18 @@ public function testVerify() $this->assertEquals("Confirm your e-mail", $doc->getElementsByTagName("title")[0]->textContent); // If this works, I'm assuming it is valid HTML. } + public function testVerifyFailure() + { + $this->expectException(\Exception::class); + + Mailer::$mailer = new MailerMock(); + Mailer::$mailer->ErrorInfo = 'Mock Error'; + Mailer::sendVerify([ + 'email' => 'alice@example.com', + 'code' => '654321' + ]); + } + public function testResetPassword() { Mailer::$mailer = new MailerMock(); From f061083ae33a969581806996cd935f9146fe00ed Mon Sep 17 00:00:00 2001 From: Ben Peachey Date: Mon, 7 Sep 2026 16:58:21 +0200 Subject: [PATCH 2/2] Fix "Constant already defined" warning. --- tests/phpunit/DbTest.php | 3 ++- tests/phpunit/MailerTest.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/DbTest.php b/tests/phpunit/DbTest.php index 1a8885f..c4b30f4 100644 --- a/tests/phpunit/DbTest.php +++ b/tests/phpunit/DbTest.php @@ -4,7 +4,8 @@ use Pdsinterop\PhpSolid\Db; -const DBPATH = ":memory:"; +defined('DBPATH') || define('DBPATH', ":memory:"); + class DbTest extends \PHPUnit\Framework\TestCase { public function testConnect() diff --git a/tests/phpunit/MailerTest.php b/tests/phpunit/MailerTest.php index 7fb5cc3..02a303e 100644 --- a/tests/phpunit/MailerTest.php +++ b/tests/phpunit/MailerTest.php @@ -17,7 +17,7 @@ const MAILSTYLES = []; -const BASEURL = "https://example.com"; +defined('BASEURL') || define('BASEURL', "https://example.com"); class MailerMock {