Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/Utopia/Messaging/Adapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ private function recordResponse(Message $message, array $response): void
* statusCode: int,
* response: array<string, mixed>|string|null,
* headers: array<string, string>,
* error: string|null
* error: string|null,
* errorCode: int
* }
*
* @throws \Exception If the request fails.
Expand Down Expand Up @@ -214,6 +215,7 @@ protected function request(
'response' => $response,
'headers' => $responseHeaders,
'error' => \curl_error($ch),
'errorCode' => \curl_errno($ch),
];
}

Expand All @@ -227,9 +229,10 @@ protected function request(
* index: int,
* url: string,
* statusCode: int,
* response: array<string, mixed>|null,
* response: array<string, mixed>|string|null,
* headers: array<string, string>,
* error: string|null
* error: string|null,
* errorCode: int
* }>
*
* @throws Exception
Expand Down Expand Up @@ -340,6 +343,7 @@ protected function requestMulti(
// capture (without copy_handle) if a multi-path adapter needs it.
'headers' => [],
'error' => \curl_error($ch),
'errorCode' => $info['result'],
];

\curl_multi_remove_handle($mh, $ch);
Expand Down
38 changes: 31 additions & 7 deletions src/Utopia/Messaging/Adapter/Push/FCM.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,16 +166,40 @@ protected function process(PushMessage $message): array
$response->incrementDeliveredTo();
$response->addResult($message->getTo()[$result['index']]);
} else {
$error =
($result['response']['error']['status'] ?? null) === 'UNREGISTERED'
|| ($result['response']['error']['status'] ?? null) === 'NOT_FOUND'
? $this->getExpiredErrorMessage()
: $result['response']['error']['message'] ?? 'Unknown error';

$response->addResult($message->getTo()[$result['index']], $error);
$response->addResult($message->getTo()[$result['index']], $this->getError($result));
}
}

return $response->toArray();
}

/**
* @param array{
* statusCode: int,
* response: array<string, mixed>|string|null,
* error: string|null,
* errorCode: int
* } $result
*/
protected function getError(array $result): string
{
$response = \is_array($result['response']) ? $result['response'] : [];
$error = \is_array($response['error'] ?? null) ? $response['error'] : [];

if (\in_array($error['status'] ?? null, ['UNREGISTERED', 'NOT_FOUND'], true)) {
return $this->getExpiredErrorMessage();
}

$message = $error['message'] ?? null;
if (\is_string($message) && $message !== '') {
return $message;
}

$transportError = $result['error'] ?? null;
$details = "HTTP status {$result['statusCode']}; cURL error code {$result['errorCode']}";

return \is_string($transportError) && $transportError !== ''
? "{$transportError} ({$details})"
: "Request failed ({$details})";
}
}
3 changes: 2 additions & 1 deletion tests/Messaging/Adapter/Email/ResendRoutingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class ResendStub extends Resend
/**
* @param array<string> $headers
* @param array<string, mixed>|null $body
* @return array{url: string, statusCode: int, response: array<string, mixed>|string|null, headers: array<string, string>, error: string|null}
* @return array{url: string, statusCode: int, response: array<string, mixed>|string|null, headers: array<string, string>, error: string|null, errorCode: int}
*/
protected function request(
string $method,
Expand All @@ -160,6 +160,7 @@ protected function request(
'response' => $stub['response'],
'headers' => [],
'error' => null,
'errorCode' => 0,
];
}
}
3 changes: 2 additions & 1 deletion tests/Messaging/Adapter/Email/SESRoutingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ class SESStub extends SES
/**
* @param array<string> $headers
* @param array<string, mixed>|null $body
* @return array{url: string, statusCode: int, response: array<string, mixed>|string|null, headers: array<string, string>, error: string|null}
* @return array{url: string, statusCode: int, response: array<string, mixed>|string|null, headers: array<string, string>, error: string|null, errorCode: int}
*/
protected function request(
string $method,
Expand All @@ -682,6 +682,7 @@ protected function request(
'response' => $stub['response'],
'headers' => $stub['headers'] ?? [],
'error' => null,
'errorCode' => 0,
];
}
}
55 changes: 55 additions & 0 deletions tests/Messaging/Adapter/Push/FCMTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Utopia\Tests\Adapter\Push;

use PHPUnit\Framework\Attributes\DataProvider;
use Utopia\Messaging\Adapter\Push\FCM as FCMAdapter;

class FCMTest extends Base
Expand All @@ -19,4 +20,58 @@ protected function getTo(): array
{
return [\getenv('FCM_TO')];
}

/**
* @param array{
* statusCode: int,
* response: array<string, mixed>|string|null,
* error: string|null,
* errorCode: int
* } $result
*/
#[DataProvider('errorProvider')]
public function testGetError(array $result, string $expected): void
{
$adapter = new class ('{}') extends FCMAdapter {
/**
* @param array{
* statusCode: int,
* response: array<string, mixed>|string|null,
* error: string|null,
* errorCode: int
* } $result
*/
public function error(array $result): string
{
return $this->getError($result);
}
};

$this->assertSame($expected, $adapter->error($result));
}

/**
* @return array<string, array{0: array<string, mixed>, 1: string}>
*/
public static function errorProvider(): array
{
return [
'firebase error message' => [
['statusCode' => 400, 'response' => ['error' => ['message' => 'Invalid registration token']], 'error' => '', 'errorCode' => 0],
'Invalid registration token',
],
'expired token' => [
['statusCode' => 404, 'response' => ['error' => ['status' => 'NOT_FOUND', 'message' => 'Requested entity was not found.']], 'error' => '', 'errorCode' => 0],
'Expired device token',
],
'transport error' => [
['statusCode' => 0, 'response' => null, 'error' => 'Connection timed out after 10000 milliseconds', 'errorCode' => 28],
'Connection timed out after 10000 milliseconds (HTTP status 0; cURL error code 28)',
],
'no error message' => [
['statusCode' => 503, 'response' => 'Service Unavailable', 'error' => '', 'errorCode' => 0],
'Request failed (HTTP status 503; cURL error code 0)',
],
];
}
}
4 changes: 3 additions & 1 deletion tests/Messaging/Adapter/SMS/Msg91Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ class Msg91TestAdapter extends Msg91
* statusCode: int,
* response: array<string, mixed>|string|null,
* headers: array<string, string>,
* error: string|null
* error: string|null,
* errorCode: int
* }
*/
protected function request(
Expand All @@ -124,6 +125,7 @@ protected function request(
'response' => [],
'headers' => [],
'error' => null,
'errorCode' => 0,
];
}
}
Loading