mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-11-12 04:25:31 +08:00
1e34a2e33b
Summary: This commit modifies the api of NylasAPIRequest to /not/ take `success` or `error` callback options at all, and only returns a Promise which you can `then` and `catch` to handle the api response. The fact that it returned a promise, and /also/ took `success` and `error` callback options made it really confusing to use. Additionaly, when using the callbacks intead of a promise, any errors would be unhandled and reported to Sentry because even though the `error` callback was being passed, the promise returned by `run()` still rejected and no one was handling that reject, so it reached the `unhandledRejection` event listener. This is undesirable because if you passed an `error` callback, it means that you intended to handle it. An example of this is calling the clearbit API, which will more often than not return a 404, and even though we had an error handler which ignored the 404, it still unecessarilly reported to Sentry, flooding it with events Test Plan: manually check all updated codepaths still work Reviewers: halla, spang, evan Reviewed By: evan Differential Revision: https://phab.nylas.com/D3869
72 lines
2.5 KiB
CoffeeScript
72 lines
2.5 KiB
CoffeeScript
# This file is in coffeescript just to use the existential operator!
|
|
{AccountStore, LegacyEdgehillAPI} = require 'nylas-exports'
|
|
|
|
MAX_RETRY = 10
|
|
|
|
module.exports = class ClearbitDataSource
|
|
clearbitAPI: ->
|
|
return "https://person.clearbit.com/v2/combined"
|
|
|
|
find: ({email, tryCount}) ->
|
|
if (tryCount ? 0) >= MAX_RETRY
|
|
return Promise.resolve(null)
|
|
new Promise (resolve, reject) =>
|
|
req = LegacyEdgehillAPI.makeRequest({
|
|
authWithNylasAPI: true
|
|
path: "/proxy/clearbit/#{@clearbitAPI()}/find?email=#{email}",
|
|
})
|
|
req.run()
|
|
.then((body) =>
|
|
@parseResponse(body, req.response.statusCode, email, tryCount).then(resolve).catch(reject)
|
|
)
|
|
|
|
# The clearbit -> Nylas adapater
|
|
parseResponse: (body={}, statusCode, requestedEmail, tryCount=0) =>
|
|
new Promise (resolve, reject) =>
|
|
# This means it's in the process of fetching. Return null so we don't
|
|
# cache and try again.
|
|
if statusCode is 202
|
|
setTimeout =>
|
|
@find({email: requestedEmail, tryCount: tryCount+1}).then(resolve).catch(reject)
|
|
, 1000
|
|
return
|
|
else if statusCode isnt 200
|
|
resolve(null)
|
|
return
|
|
|
|
person = body.person
|
|
|
|
# This means there was no data about the person available. Return a
|
|
# valid, but empty object for us to cache. This can happen when we
|
|
# have company data, but no personal data.
|
|
if not person
|
|
person = {email: requestedEmail}
|
|
|
|
resolve({
|
|
cacheDate: Date.now()
|
|
email: requestedEmail # Used as checksum
|
|
bio: person.bio ? person.twitter?.bio ? person.aboutme?.bio,
|
|
location: person.location ? person.geo?.city
|
|
currentTitle: person.employment?.title,
|
|
currentEmployer: person.employment?.name,
|
|
profilePhotoUrl: person.avatar,
|
|
rawClearbitData: body,
|
|
socialProfiles: @_socialProfiles(person)
|
|
})
|
|
|
|
_socialProfiles: (person={}) ->
|
|
profiles = {}
|
|
if (person.twitter?.handle ? "").length > 0
|
|
profiles.twitter =
|
|
handle: person.twitter.handle
|
|
url: "https://twitter.com/#{person.twitter.handle}"
|
|
if (person.facebook?.handle ? "").length > 0
|
|
profiles.facebook =
|
|
handle: person.facebook.handle
|
|
url: "https://facebook.com/#{person.facebook.handle}"
|
|
if (person.linkedin?.handle ? "").length > 0
|
|
profiles.linkedin =
|
|
handle: person.linkedin.handle
|
|
url: "https://linkedin.com/#{person.linkedin.handle}"
|
|
|
|
return profiles
|