diff --git a/spec/tasks/send-draft-spec.coffee b/spec/tasks/send-draft-spec.coffee index 9753d3fd2..861b378fb 100644 --- a/spec/tasks/send-draft-spec.coffee +++ b/spec/tasks/send-draft-spec.coffee @@ -214,6 +214,51 @@ describe "SendDraftTask", -> expect(status[1]).toBe thrownError expect(Actions.draftSendingFailed).toHaveBeenCalled() + it "presents helpful error messages for 402 errors (security blocked)", -> + thrownError = new APIError(statusCode: 402, body: { + "message": "Message content rejected for security reasons", + "server_error": "552 : 5.7.0 This message was blocked because its content presents a potential\n5.7.0 security issue. Please visit\n5.7.0 https://support.google.com/mail/answer/6590 to review our message\n5.7.0 content and attachment content guidelines. fk9sm21147314pad.9 - gsmtp", + "type": "api_error" + }) + + expectedMessage = + """ + Sorry, this message could not be sent because it was rejected by your mail provider. (Message content rejected for security reasons) + + 552 : 5.7.0 This message was blocked because its content presents a potential + 5.7.0 security issue. Please visit + 5.7.0 https://support.google.com/mail/answer/6590 to review our message + 5.7.0 content and attachment content guidelines. fk9sm21147314pad.9 - gsmtp + """ + + spyOn(NylasEnv, "reportError") + spyOn(NylasAPI, 'makeRequest').andCallFake (options) => + Promise.reject(thrownError) + waitsForPromise => @task.performRemote().then (status) => + expect(status[0]).toBe Task.Status.Failed + expect(status[1]).toBe thrownError + expect(Actions.draftSendingFailed).toHaveBeenCalled() + expect(Actions.draftSendingFailed.calls[0].args[0].errorMessage).toEqual(expectedMessage) + + it "presents helpful error messages for 402 errors (recipient failed)", -> + thrownError = new APIError(statusCode: 402, body: { + "message": "Sending to at least one recipient failed.", + "server_error": "<>", + "type": "api_error" + }) + + expectedMessage = "This message could not be delivered to at least one recipient. (Note: other recipients may have received this message - you should check Sent Mail before re-sending this message.)" + + spyOn(NylasEnv, "reportError") + spyOn(NylasAPI, 'makeRequest').andCallFake (options) => + Promise.reject(thrownError) + waitsForPromise => @task.performRemote().then (status) => + expect(status[0]).toBe Task.Status.Failed + expect(status[1]).toBe thrownError + expect(Actions.draftSendingFailed).toHaveBeenCalled() + expect(Actions.draftSendingFailed.calls[0].args[0].errorMessage).toEqual(expectedMessage) + + it "retries on timeouts", -> thrownError = new APIError(statusCode: NylasAPI.TimeoutErrorCode, body: "err") spyOn(NylasAPI, 'makeRequest').andCallFake (options) => diff --git a/src/flux/nylas-api.coffee b/src/flux/nylas-api.coffee index fb9207bc0..728480ead 100644 --- a/src/flux/nylas-api.coffee +++ b/src/flux/nylas-api.coffee @@ -11,7 +11,7 @@ async = require 'async' # A 0 code is when an error returns without a status code. These are # things like "ESOCKETTIMEDOUT" TimeoutErrorCode = 0 -PermanentErrorCodes = [400, 401, 403, 404, 405, 500] +PermanentErrorCodes = [400, 401, 402, 403, 404, 405, 500] CancelledErrorCode = -123 SampleTemporaryErrorCode = 504 diff --git a/src/flux/tasks/send-draft.coffee b/src/flux/tasks/send-draft.coffee index 32871901c..27736374e 100644 --- a/src/flux/tasks/send-draft.coffee +++ b/src/flux/tasks/send-draft.coffee @@ -211,9 +211,18 @@ class SendDraftTask extends Task if err instanceof APIError and not (err.statusCode in NylasAPI.PermanentErrorCodes) return Promise.resolve(Task.Status.Retry) else + message = "Sorry, this message could not be sent. Please try again, and make sure your message is addressed correctly and is not too large." + if err.statusCode is 402 and err.body.message + if err.body.message.indexOf('at least one recipient') isnt -1 + message = "This message could not be delivered to at least one recipient. (Note: other recipients may have received this message - you should check Sent Mail before re-sending this message.)" + else + message = "Sorry, this message could not be sent because it was rejected by your mail provider. (#{err.body.message})" + if err.body.server_error + message += "\n\n" + err.body.server_error + Actions.draftSendingFailed threadId: @draft.threadId draftClientId: @draft.clientId, - errorMessage: "Your message could not be sent. Check your network connection and try again." + errorMessage: message NylasEnv.reportError(err) return Promise.resolve([Task.Status.Failed, err])