sendinblue / APIv3-java-library

SendinBlue's API v3 Java Library
MIT License
42 stars 12 forks source link

Bad Request in logs not very informative #22

Closed nicobao closed 3 years ago

nicobao commented 3 years ago

Hi,

I use the following code snippet:

public String sendMail(String toEmail, String toName, Long templateId, Object params)
            throws ServiceImplException, NotAllowedException {
            ApiClient defaultClient = Configuration.getDefaultApiClient(); 
            // ApiKeyAuth apiKey = (ApiKeyAuth) defaultClient.getAuthentication("api-key");
            // apiKey.setApiKey(mailerApiKey);
            defaultClient.setApiKey(mailerApiKey);
            SmtpApi apiInstance = new SmtpApi();
            apiInstance.setApiClient(defaultClient);
            // ApiClient defaultClient = Configuration.getDefaultApiClient();
            // defaultClient.setApiKey(mailerApiKey);
            // apiInstance.setApiClient(defaultClient);

            SendSmtpEmail sendEmail = new SendSmtpEmail();

            sendEmail.setTemplateId(templateId);

            List<SendSmtpEmailTo> to = new ArrayList<>();
            SendSmtpEmailTo recipient = new SendSmtpEmailTo();
            recipient.setEmail(toEmail);
            recipient.setName(toName);
            to.add(recipient);
            sendEmail.setTo(to);

            List<SendSmtpEmailBcc> bccList = new ArrayList<>();
            SendSmtpEmailBcc bcc = new SendSmtpEmailBcc();
            bcc.setEmail("support@example.com");
            bccList.add(bcc);
            sendEmail.setBcc(bccList);

            SendSmtpEmailReplyTo replyTo = new SendSmtpEmailReplyTo();
            replyTo.setEmail("support@example.com");
            replyTo.setName("EXAMPLE");
            sendEmail.setReplyTo(replyTo);

            try {
                CreateSmtpEmail result = apiInstance.sendTransacEmail(sendEmail);
                LOGGER.info("[Email] templateId " + templateId + " to " + toEmail + " (" + toName
                        + ") with params + " + params + " successfully sent. Result messageId: "
                        + result.getMessageId());
                return result.getMessageId();
            } catch (ApiException ex) {
                throw new ServiceImplException(
                        "[Email] templateId " + templateId + " to " + toEmail + " (" + toName + ") failed", ex);
            }
}

and receive an exception sendinblue.ApiException: Bad Request without more information. Could it be possible to return more helpful message about what exactly in the message was incorrect? Is it authentification? Is it something else? How can I log the JSON that's attempting to be sent? (if it can ever get serialized?)

nicobao commented 3 years ago

Also, what is the partner-key about, please? I don't see anything about this anywhere in your doc, nor in your web app.

mourraille commented 3 years ago

Also, what is the partner-key about, please? I don't see anything about this anywhere in your doc, nor in your web app.

Hi @nicobao , you can remove these code lines. You should only need your Sendinblue api key. Which can be found/generated here: https://account.sendinblue.com/advanced/api

mourraille commented 3 years ago

You only want to use these lines:

ApiKeyAuth apiKey = (ApiKeyAuth) defaultClient.getAuthentication("api-key"); apiKey.setApiKey(mailerApiKey);

nicobao commented 3 years ago

Thank you for the quick reply, but it did not answer my issue.

I was doing what you suggest initially following: https://github.com/sendinblue/APIv3-java-library/blob/master/docs/SmtpApi.md#sendtransacemail and still got the Bad Request. Indeed I realize both the solutions presented in your doc (and that you suggested) and the one I tried, were correct.

When I try with putting dummy authentication key as follows: apiKey.setApiKey("test") I got sendinblue.ApiException: Unauthorized, which means I was correctly authenticated when receiving Bad Request.

I also discovered how to pretty print better error messages from your sendinblue.ApiException class. You need to manually print "ex.getResponseBody()" as follows:

            try {
                CreateSmtpEmail result = apiInstance.sendTransacEmail(thisEmailWillThrowAnException);
                return result.getMessageId();
            } catch (ApiException ex) {

                throw new ServiceImplException(
                        "[Email] templateId " + templateId + " to " + toEmail + " (" + toName + ") failed: "
                                + ex.getResponseBody(),
                        ex);
            }

so that you get something like:

io.company.product.exception.ServiceImplException: [Email] templateId null to john.doo@example.com (null) failed: {"code":"missing_parameter","message":"sender is missing"}

You can also use ex.getCode() or ex.getResponseHeaders().

I feel like those info should already be in the message of the ApiException so that you can just do LOGGER.error("My message", apiException), but I'm not sure how idiomatic it is in Java. I don't see any situation when one wouldn't want to log that info though...