Skip to content

Commit aa1e12c

Browse files
alamiraultfabpot
authored andcommitted
[symfony/mailjet-mailer] Fix invalid mailjet error managment
1 parent 9bc4468 commit aa1e12c

File tree

2 files changed

+185
-2
lines changed

2 files changed

+185
-2
lines changed

src/Symfony/Component/Mailer/Bridge/Mailjet/Tests/Transport/MailjetApiTransportTest.php

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
namespace Symfony\Component\Mailer\Bridge\Mailjet\Tests\Transport;
44

55
use PHPUnit\Framework\TestCase;
6+
use Symfony\Component\HttpClient\MockHttpClient;
7+
use Symfony\Component\HttpClient\Response\MockResponse;
68
use Symfony\Component\Mailer\Bridge\Mailjet\Transport\MailjetApiTransport;
79
use Symfony\Component\Mailer\Envelope;
10+
use Symfony\Component\Mailer\Exception\HttpTransportException;
11+
use Symfony\Component\Mailer\SentMessage;
812
use Symfony\Component\Mime\Address;
913
use Symfony\Component\Mime\Email;
1014

@@ -85,6 +89,183 @@ public function testPayloadFormat()
8589
$this->assertEquals('Qux', $replyTo['Name']);
8690
}
8791

92+
public function testSendSuccess()
93+
{
94+
$json = json_encode([
95+
'Messages' => [
96+
'foo' => 'bar',
97+
],
98+
]);
99+
100+
$responseHeaders = [
101+
'x-mj-request-guid' => ['baz'],
102+
];
103+
104+
$response = new MockResponse($json, ['response_headers' => $responseHeaders]);
105+
106+
$client = new MockHttpClient($response);
107+
108+
$transport = new MailjetApiTransport(self::USER, self::PASSWORD, $client);
109+
110+
$email = new Email();
111+
$email
112+
113+
114+
->text('foobar');
115+
116+
$sentMessage = $transport->send($email);
117+
$this->assertInstanceOf(SentMessage::class, $sentMessage);
118+
$this->assertSame('baz', $sentMessage->getMessageId());
119+
}
120+
121+
public function testSendWithDecodingException()
122+
{
123+
$response = new MockResponse('cannot-be-decoded');
124+
125+
$client = new MockHttpClient($response);
126+
127+
$transport = new MailjetApiTransport(self::USER, self::PASSWORD, $client);
128+
129+
$email = new Email();
130+
$email
131+
132+
133+
->text('foobar');
134+
135+
$this->expectExceptionObject(
136+
new HttpTransportException('Unable to send an email: "cannot-be-decoded" (code 200).', $response)
137+
);
138+
139+
$transport->send($email);
140+
}
141+
142+
public function testSendWithTransportException()
143+
{
144+
$response = new MockResponse('', ['error' => 'foo']);
145+
146+
$client = new MockHttpClient($response);
147+
148+
$transport = new MailjetApiTransport(self::USER, self::PASSWORD, $client);
149+
150+
$email = new Email();
151+
$email
152+
153+
154+
->text('foobar');
155+
156+
$this->expectExceptionObject(
157+
new HttpTransportException('Could not reach the remote Mailjet server.', $response)
158+
);
159+
160+
$transport->send($email);
161+
}
162+
163+
public function testSendWithBadRequestResponse()
164+
{
165+
$json = json_encode([
166+
'Messages' => [
167+
[
168+
'Errors' => [
169+
[
170+
'ErrorIdentifier' => '8e28ac9c-1fd7-41ad-825f-1d60bc459189',
171+
'ErrorCode' => 'mj-0005',
172+
'StatusCode' => 400,
173+
'ErrorMessage' => 'The To is mandatory but missing from the input',
174+
'ErrorRelatedTo' => ['To'],
175+
],
176+
],
177+
'Status' => 'error',
178+
],
179+
],
180+
]);
181+
182+
$response = new MockResponse($json, ['http_code' => 400]);
183+
184+
$client = new MockHttpClient($response);
185+
186+
$transport = new MailjetApiTransport(self::USER, self::PASSWORD, $client);
187+
188+
$email = new Email();
189+
$email
190+
191+
192+
->text('foobar');
193+
194+
$this->expectExceptionObject(
195+
new HttpTransportException('Unable to send an email: "The To is mandatory but missing from the input" (code 400).', $response)
196+
);
197+
198+
$transport->send($email);
199+
}
200+
201+
public function testSendWithNoErrorMessageBadRequestResponse()
202+
{
203+
$response = new MockResponse('response-content', ['http_code' => 400]);
204+
205+
$client = new MockHttpClient($response);
206+
207+
$transport = new MailjetApiTransport(self::USER, self::PASSWORD, $client);
208+
209+
$email = new Email();
210+
$email
211+
212+
213+
->text('foobar');
214+
215+
$this->expectExceptionObject(
216+
new HttpTransportException('Unable to send an email: "response-content" (code 400).', $response)
217+
);
218+
219+
$transport->send($email);
220+
}
221+
222+
/**
223+
* @dataProvider getMalformedResponse
224+
*/
225+
public function testSendWithMalformedResponse(array $body)
226+
{
227+
$json = json_encode($body);
228+
229+
$response = new MockResponse($json);
230+
231+
$client = new MockHttpClient($response);
232+
233+
$transport = new MailjetApiTransport(self::USER, self::PASSWORD, $client);
234+
235+
$email = new Email();
236+
$email
237+
238+
239+
->text('foobar');
240+
241+
$this->expectExceptionObject(
242+
new HttpTransportException(sprintf('Unable to send an email: "%s" malformed api response.', $json), $response)
243+
);
244+
245+
$transport->send($email);
246+
}
247+
248+
public function getMalformedResponse(): \Generator
249+
{
250+
yield 'Missing Messages key' => [
251+
[
252+
'foo' => 'bar',
253+
],
254+
];
255+
256+
yield 'Messages is not an array' => [
257+
[
258+
'Messages' => 'bar',
259+
],
260+
];
261+
262+
yield 'Messages is an empty array' => [
263+
[
264+
'Messages' => [],
265+
],
266+
];
267+
}
268+
88269
public function testReplyTo()
89270
{
90271
$from = '[email protected]';

src/Symfony/Component/Mailer/Bridge/Mailjet/Transport/MailjetApiTransport.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,15 @@ protected function doSendApi(SentMessage $sentMessage, Email $email, Envelope $e
6969
$statusCode = $response->getStatusCode();
7070
$result = $response->toArray(false);
7171
} catch (DecodingExceptionInterface $e) {
72-
throw new HttpTransportException('Unable to send an email: '.$response->getContent(false).sprintf(' (code %d).', $statusCode), $response);
72+
throw new HttpTransportException(sprintf('Unable to send an email: "%s" (code %d).', $response->getContent(false), $statusCode), $response);
7373
} catch (TransportExceptionInterface $e) {
7474
throw new HttpTransportException('Could not reach the remote Mailjet server.', $response, 0, $e);
7575
}
7676

7777
if (200 !== $statusCode) {
78-
throw new HttpTransportException('Unable to send an email: '.$result['Message'].sprintf(' (code %d).', $statusCode), $response);
78+
$errorDetails = $result['Messages'][0]['Errors'][0]['ErrorMessage'] ?? $response->getContent(false);
79+
80+
throw new HttpTransportException(sprintf('Unable to send an email: "%s" (code %d).', $errorDetails, $statusCode), $response);
7981
}
8082

8183
// The response needs to contains a 'Messages' key that is an array

0 commit comments

Comments
 (0)