Skip to content

Latest commit

 

History

History
216 lines (150 loc) · 10.3 KB

TROUBLESHOOTING.md

File metadata and controls

216 lines (150 loc) · 10.3 KB

If you have an issue logging into your Twilio SendGrid account, please read this document. For any questions regarding login issues, please contact our support team.

If you have a non-library Twilio SendGrid issue, please contact our support team.

Table of Contents

Continue Using the v2 API

Here is the last working version with v2 support.

Using Nuget:

PM> Install-Package Sendgrid -Version 6.3.4

Download:

Click the "Clone or download" green button in GitHub and choose download.

Environment Variables and Your Twilio SendGrid API Key

All of our examples assume you are using environment variables to hold your Twilio SendGrid API key.

If you choose to add your Twilio SendGrid API key directly (not recommended):

string apiKey = Environment.GetEnvironmentVariable("SENDGRID_API_KEY");

becomes

string apiKey = "SENDGRID_API_KEY";

In the first case, SENDGRID_API_KEY is in reference to the name of the environment variable, while the second case references the actual Twilio SendGrid API Key.

Error Messages

By default if the API returns an error, it doesn't throw an exception, but you can read the error message returned by Twilio SendGrid's API:

var response = await client.RequestAsync(method: SendGridClient.Method.POST,
                                         requestBody: msg.Serialize(),
                                         urlPath: "mail/send");
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Body.ReadAsStringAsync().Result); // The message will be here
Console.WriteLine(response.Headers.ToString());

If you want to throw the exception when the API returns an error, init the SendGridClient with options including 'HttpErrorAsException' as true:

var client = new SendGridClient(new SendGridClientOptions{ ApiKey = apiKey, HttpErrorAsException = true });

Then if an error is thrown due to a failed request, a summary of that error along with a link to the appropriate place in the documentation will be sent back as a JSON object in the Exception Message. You can also deserialize the JSON object as a SendGridErrorResponse. Every error status code returned by the API has its own type of exception (BadRequestException, UnauthorizedException, PayloadTooLargeException, SendGridInternalException, etc.). All the possibles status codes and errors are documented here.

EXAMPLES

401 - Unauthorized

var client = new SendGridClient(new SendGridClientOptions{ ApiKey = "SG.12345678901234567890123456789012", HttpErrorAsException = true });

try
{
    var response = await client.RequestAsync(method: SendGridClient.Method.POST,
                                             requestBody: msg.Serialize(),
                                             urlPath: "mail/send");
}
catch(Exception ex)
{
    SendGridErrorResponse errorResponse = JsonConvert.DeserializeObject<SendGridErrorResponse>(ex.Message);
    Console.WriteLine(ex.Message);
    //{
    //  "ErrorHttpStatusCode":401,
    //  "ErrorReasonPhrase":"Unauthorized",
    //  "SendGridErrorMessage":"Permission denied, wrong credentials",
    //  "FieldWithError":null,
    //  "HelpLink":null
    //}
}

400 - Bad Request - From Email Null

var client = new SendGridClient(new SendGridClientOptions{ ApiKey = apiKey, HttpErrorAsException = true });

try
{
    var from = new EmailAddress("", "Example User"); // From email null
    var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);

    var response = await client.SendEmailAsync(msg).ConfigureAwait(false);
}
catch (Exception ex)
{
    SendGridErrorResponse errorResponse = JsonConvert.DeserializeObject<SendGridErrorResponse>(ex.Message);
    Console.WriteLine(ex.Message);
    //{
    //  "ErrorHttpStatusCode":400,
    //  "ErrorReasonPhrase":"Bad Request",
    //  "SendGridErrorMessage":"The from email does not contain a valid address.",
    //  "FieldWithError":"from.email",
    //  "HelpLink":"http://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html#message.from"
    //}
}

Migrating from the v2 API to v3

Please review our guide on how to migrate from v2 to v3.

Migrating from the v8 SDK to v9

v9 of this SDK is a complete rewrite that includes the removal of dynamic dependencies, a new Mail Helper and support for .NET Standard 1.3.

Please begin at the README.

Missing Classes

If you receive one of the following errors, or something similar:

  • ‘Helpers’ does not exist in the namespace ‘SengrGrid’
  • The type or namespace name ‘Mail’ could not be found

it means that you are probably not compiling your application to .NET 4.5.2. Currently, this is the only supported version of .NET by Twilio SendGrid.

The current solution is to download the code directly into your project and change the compile target to the desired version.

Testing v3 /mail/send Calls Directly

Here are some cURL examples for common use cases.

Using .NET 4.5.1 and lower

Microsoft is no longer supporting these versions. We strongly advise upgrading your software to target .NET 4.5.2 or higher. If you are unable to do so, the current solution is to download the code directly into your project and change the compile target to the desired version.

Using the Package Manager

We upload this library to Nuget whenever we make a release. This allows you to use Nuget for easy installation.

In most cases we recommend you download the latest version of the library, but if you need a different version, please use:

PM> Install-Package Sendgrid -Version X.X.X

Versioning Convention

We follow the MAJOR.MINOR.PATCH versioning scheme as described by SemVer.org. Therefore, we recommend that you always pin (or vendor) the particular version you are working with your code and never auto-update to the latest version. Especially when there is a MAJOR point release since that is guaranteed to be a breaking change. Changes are documented in the CHANGELOG and releases section.

Viewing the Request Body

When debugging or testing, it may be useful to examine the raw request body to compare against the documented format.

You can do this right before you call var response = await client.SendEmailAsync(msg); like so:

Console.WriteLine(msg.Serialize());

UI Requests are Failing / Deadlocks

If your UI based requests are failing, it may be due to a little known issue where the UI only has a single thread. The answer here is to use ConfigureAwait(false) on the end of your request call so that the thread does not reset back to request context and stays in capture context. Normally, async the request thread would "let go" of the capture context and reset to request context. With the UI, there is only a single thread, so you have to force the thread to switch to capture context, using ConfigureAwait(false). For more information, please see a better summary that is linked to a longer article in StackOverflow.

In our example code, you would change:

var response = await client.SendEmailAsync(msg);

to

var response = await client.SendEmailAsync(msg).ConfigureAwait(false);

If you are running a newer versions of .NET you can turn on a couple different Roslyn based analyzers that will trigger build errors if you're not calling .ConfigureAwait(false) on your async methods.

Roslynator.Analyzers can be installed through NuGet or as a VS plugin, but if you use the plugin then the analyzers won't run on build servers and trigger build errors as the NuGet package would. (thanks to xt0rted for this tip!)

Signed Webhook Verification

Twilio SendGrid's Event Webhook will notify a URL via HTTP POST with information about events that occur as your mail is processed. This article covers all you need to know to secure the Event Webhook, allowing you to verify that incoming requests originate from Twilio SendGrid. The sendgrid-csharp library can help you verify these Signed Event Webhooks.

You can find the end-to-end usage example and the tests here. If you are still having trouble getting the validation to work, follow the following instructions:

  • Be sure to use the raw payload for validation
  • Be sure to include a trailing carriage return and newline in your payload
  • In case of multi-event webhooks, make sure you include the trailing newline and carriage return after each event