Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fatal error: Uncaught SendGrid\Mail\TypeException #900

Closed
Robin-the-Frog opened this issue Oct 30, 2019 · 9 comments
Closed

Fatal error: Uncaught SendGrid\Mail\TypeException #900

Robin-the-Frog opened this issue Oct 30, 2019 · 9 comments
Labels
difficulty: unknown or n/a fix is unknown in difficulty status: waiting for feedback waiting for feedback from the submitter type: question question directed at the library

Comments

@Robin-the-Frog
Copy link

Robin-the-Frog commented Oct 30, 2019

I tried searching and this doesn't appear to have come up anywhere. I'm surprised, surely this isn't new??

Issue Summary

As part of my testing I tried entering an invalid email address (incorrectly formatted - robin@excellentconsul i.e. no .co.uk on the end)

Running the sendmail.php page gives the error:

Fatal error: Uncaught SendGrid\Mail\TypeException: $emailAddress must be valid and of type string. in /var/sites/d/mydomain.co.uk/public_html/sendgrid/lib/mail/EmailAddress.php:76 Stack trace: #0 /var/sites/d/mydomain.co.uk/public_html/sendgrid/lib/mail/EmailAddress.php(51): SendGrid\Mail\EmailAddress->setEmailAddress('robin@excellent...') #1 /var/sites/d/mydomain.co.uk/public_html/sendgrid/lib/mail/Mail.php(199): SendGrid\Mail\EmailAddress->__construct('robin@excellent...', 'Robin Miller', Array) #2 /var/sites/d/mydomain.co.uk/public_html/sendgrid/lib/mail/Mail.php(362): SendGrid\Mail\Mail->addRecipientEmail('\SendGrid\Mail\...', 'robin@excellent...', 'Robin Miller', Array, NULL, NULL) #3 /var/sites/d/mydomain.co.uk/public_html/emailtest-sendgrid.php(43): SendGrid\Mail\Mail->addTo('robin@excellent...', 'Robin Miller', Array) #4 {main} thrown in /var/sites/d/mydomain.co.uk/public_html/sendgrid/lib/mail/EmailAddress.php on line 76

EmailAddress.php line 76 says:
throw new TypeException(

The catch exception on my sendemail.php page (same as the suggested default code) says:
} catch (Exception $e) {

I'm no php expert, far from it! But from a little googling, https://wiki.php.net/rfc/throwable-interface
seems to suggest that 'Exception' and 'TypeException' are 2 different things, hence the catch Exception on the sendmail page is not catching the TypeException thrown by EmailAddress.php

Any ideas?

(I checked in the File Repository here on GH just in case I somehow managed to get an old verison but it's there as well.)

As I say, surely this isn't a new issue??!

Technical details:

  • sendgrid-php Version:
    How do I see which version I have? The latest I assume, I only downloaded it 2 days ago
  • PHP Version: 7.3
@Robin-the-Frog
Copy link
Author

OK, so I've found /lib/mail/TypeException.php but we're now outside my php knowledge.
So, can someone explain why I'm getting the fatal error please?!

@Robin-the-Frog
Copy link
Author

Robin-the-Frog commented Nov 6, 2019

This is a guess, but is it because /lib/loader doesn't include
require_once __DIR__ . '/mail/TypeException.php';
in it when it should??

@thinkingserious
Copy link
Contributor

Hello @Robin-the-Frog,

Thanks for taking the time to report this!

Could you please try the following?

<?php
require 'vendor/autoload.php';

$email = new \SendGrid\Mail\Mail(); 
$email->setFrom("ethomas@twilio.com", "Elmer Thomas");
$email->setSubject("Sending with Twilio SendGrid is Fun");
try {
    $email->addTo("test@example", "Bad User");
} catch (SendGrid\Mail\TypeException $e) {
    echo 'Caught type exception: '. $e->getMessage() ."\n";
}
$email->addContent("text/plain", "and easy to do anywhere, even with PHP");
$email->addContent(
    "text/html", "<strong>and easy to do anywhere, even with PHP</strong>"
);
$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY'));
try {
    $response = $sendgrid->send($email);
    print $response->statusCode() . "\n";
    print_r($response->headers());
    print $response->body() . "\n";
} catch (Exception $e) {
    echo 'Caught exception: '. $e->getMessage() ."\n";
}

Here is my result:

Caught type exception: test@example must be valid and of type string.
400
Array
(
    [0] => HTTP/1.1 400 Bad Request
    [1] => Server: nginx
    [2] => Date: Fri, 08 Nov 2019 22:20:52 GMT
    [3] => Content-Type: application/json
    [4] => Content-Length: 237
    [5] => Connection: keep-alive
    [6] => Access-Control-Allow-Origin: https://sendgrid.api-docs.io
    [7] => Access-Control-Allow-Methods: POST
    [8] => Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl
    [9] => Access-Control-Max-Age: 600
    [10] => X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html
    [11] => 
    [12] => 
)
{"errors":[{"message":"The personalizations field is required and must have at least one personalization.","field":"personalizations","help":"http://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html#-Personalizations-Errors"}]}

With best regards,

Elmer

@thinkingserious thinkingserious added difficulty: unknown or n/a fix is unknown in difficulty status: waiting for feedback waiting for feedback from the submitter type: question question directed at the library labels Nov 8, 2019
@Robin-the-Frog
Copy link
Author

Hi Elmer

Thanks for investigating.
Ah, I see, you've added another try catch block.

This is what I get (It's almost exactly the same as yours except my response_body is not quite a full as yours):-

Caught type exception: $emailAddress must be valid and of type string.

400

Array ( [0] => HTTP/1.1 400 Bad Request [1] => Server: nginx [2] => Date: Sun, 10 Nov 2019 16:20:26 GMT [3] => Content-Type: application/json [4] => Content-Length: 110 [5] => Connection: keep-alive [6] => Access-Control-Allow-Origin: https://sendgrid.api-docs.io [7] => Access-Control-Allow-Methods: POST [8] => Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl [9] => Access-Control-Max-Age: 600 [10] => X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html [11] => [12] => )

{"errors":[{"message":"The personalization block may not be null.","field":"personalizations.0","help":null}]}

@Graloth
Copy link

Graloth commented Nov 13, 2019

It might be worth looking at using Throwable instead of Exception when catching, that way you catch all throws, not just exceptions. You can read about it here: https://www.php.net/manual/en/class.throwable.php

This is also mentioned in the link provided in the issue description, and has been available in PHP for a few years to my knowledge.

@kampalex
Copy link
Contributor

kampalex commented Dec 4, 2019

@Robin-the-Frog You ran in 2 issues:
First, a TypeException is thrown in a place you didn't expect to have one. Due to the missing @throws TypeException PHPDoc in the EmailAddress constructor, f.e. PhpStorm don't tells about it. It seems that every method in this constructor can throw TypeException.
(I will try to contribute for PHPDoc issues in separate PR - a lot of these entries are missing in other files.)

Maybe splitting your code in preparation (validation) and execution (combine together and send) will help you in preventing issues. Otherwise your complete code (from constructing Mail to send) must be in try-catch block. (After a quick review of the published examples, no one has the try-catch TypeException structures.)

Second issue is that @thinkingserious code didn't interrupt execution after catching the error. This causes even more confusion due to the failing API result. The cause of the failure is that no To recipients were assigned onto 'empty' Personalization (created by Mail constructor without arguments), so API responded an error because it was serialized to null. This one may be fixed in master #686 (not tested).

When just sending a single message, these lines of code will work for you.
Of course, customize by your needs.
(Release version 7.3.0 - PHP 7.3.12)

use SendGrid;
use SendGrid\Mail\Mail;
use SendGrid\Mail\From;
use SendGrid\Mail\To;
use SendGrid\Mail\Subject;
use SendGrid\Mail\Content;
use SendGrid\Mail\TypeException;

//  Not having the SendGrid apiKey? Reject
$apiKey = getenv('SENDGRID_API_KEY');
if (!is_string($apiKey)) {
    echo "SendGrid API key is missing";
    exit;
}

try {
    //  Compose parameters which may be fail
    $mailFrom = new From("valid-address@sendgrid.com", "Valid sender");
    $mailTo = new To("test@example", "Bad User");
    $mailSubject = new Subject("Sending with Twilio SendGrid is Fun");

    //  Contents
    $mailContentPlain = new Content("text/plain", "and easy to do anywhere, even with PHP");
    $mailContentHtml = new Content("text/html", "<strong>and easy to do anywhere, even with PHP</strong>");
} catch (TypeException $e) {
    //  Your parameters are failing!
    echo 'Parameter exception: ' . $e->getMessage() . "\n";
    exit;
}

try {
    //  Create the Mail and try to send it
    $mail = new Mail($mailFrom, $mailTo, $mailSubject, $mailContentPlain, $mailContentHtml);
    $client = new SendGrid($apiKey);

    //  Try to send the mail which is composed
    $response = $client->send($mail);

    //  Handle/print the response
    print $response->statusCode() . "\n";
    print_r($response->headers());
    print $response->body() . "\n";
} catch (Exception $e) {
    //  SendGrid is failing...
    echo 'SendGrid exception: ' . $e->getMessage() . "\n";
    exit;
}

After fixing the 'Bad user', the message will be sent.

@kampalex
Copy link
Contributor

kampalex commented Dec 6, 2019

Damn... this may had be prevented if pull requests like this one of last year(!) was merged into a release.

@kampalex

This comment has been minimized.

@7aklhz
Copy link

7aklhz commented Jan 22, 2021

thank you @kampalex for your response. I noticed I was actually using the same variable for defining my sendgrid and for my POST value. This was causing the error. I removed my comment so it doesn't create a confusion for future readers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
difficulty: unknown or n/a fix is unknown in difficulty status: waiting for feedback waiting for feedback from the submitter type: question question directed at the library
Projects
None yet
Development

No branches or pull requests

6 participants