diff --git a/package.json b/package.json index 7621e8b55..55215b5da 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": { "analytics-node": "^2.1.1", "apollo-client": "^1.0.1", + "apollo-errors": "^1.4.0", "babel-runtime": "^6.18.0", "bcrypt": "^0.8.7", "body-parser": "^1.15.2", diff --git a/packages/vulcan-base-components/lib/common/Newsletter.jsx b/packages/vulcan-base-components/lib/common/Newsletter.jsx index 68159df3a..a673890d5 100644 --- a/packages/vulcan-base-components/lib/common/Newsletter.jsx +++ b/packages/vulcan-base-components/lib/common/Newsletter.jsx @@ -32,11 +32,10 @@ class Newsletter extends PureComponent { const result = await this.props.addEmailNewsletter({email: data.email}); this.successCallbackSubscription(result); } catch(error) { - console.error(error); // eslint-disable-line no-console - this.props.flash( - this.context.intl.formatMessage(Utils.decodeIntlError(error)), - "error" - ); + const graphQLError = error.graphQLErrors[0]; + console.error(graphQLError); // eslint-disable-line no-console + const message = this.context.intl.formatMessage({id: `newsletter.error_${this.state.error.name}`}, {message: this.state.error.message}); + this.props.flash(message, 'error'); } } diff --git a/packages/vulcan-lib/lib/server/apollo_server.js b/packages/vulcan-lib/lib/server/apollo_server.js index 6df1198ac..573a621a4 100644 --- a/packages/vulcan-lib/lib/server/apollo_server.js +++ b/packages/vulcan-lib/lib/server/apollo_server.js @@ -5,6 +5,7 @@ import { makeExecutableSchema } from 'graphql-tools'; import deepmerge from 'deepmerge'; import OpticsAgent from 'optics-agent' import DataLoader from 'dataloader'; +import { formatError } from 'apollo-errors'; import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; @@ -111,6 +112,9 @@ const createApolloServer = (givenOptions = {}, givenConfig = {}) => { options.context[collection.options.collectionName].loader = new DataLoader(ids => findByIds(collection, ids, options.context), { cache: true }); }); + // add error formatting from apollo-errors + options.formatError = formatError; + return options; })); diff --git a/packages/vulcan-newsletter/lib/modules/i18n.js b/packages/vulcan-newsletter/lib/modules/i18n.js new file mode 100644 index 000000000..e560e971d --- /dev/null +++ b/packages/vulcan-newsletter/lib/modules/i18n.js @@ -0,0 +1,8 @@ +import { addStrings } from 'meteor/vulcan:core'; + +addStrings('en', { + 'newsletter.error_invalid_email': `Sorry, that doesn't look like a valid email.`, + 'newsletter.error_already_subscribed': `Sorry, it looks like you're already subscribed to the list.`, + 'newsletter.error_has_unsubscribed': `Sorry, it looks like you've previously unsubscribed from the list, and we're not able to re-subscribe you automatically.`, + 'newsletter.error_subscription_failed': `Sorry, your subscription failed ({message}).`, +}); \ No newline at end of file diff --git a/packages/vulcan-newsletter/lib/modules/index.js b/packages/vulcan-newsletter/lib/modules/index.js index 1b722c5d8..4d1074c02 100644 --- a/packages/vulcan-newsletter/lib/modules/index.js +++ b/packages/vulcan-newsletter/lib/modules/index.js @@ -3,6 +3,7 @@ import Newsletters from './collection.js'; import './emails.js'; import './custom_fields.js'; import './fragments.js'; +import './i18n.js'; import '../components/NewsletterSubscribe.jsx'; diff --git a/packages/vulcan-newsletter/lib/server/integrations/mailchimp.js b/packages/vulcan-newsletter/lib/server/integrations/mailchimp.js index 8e53ecf09..36ee06eab 100644 --- a/packages/vulcan-newsletter/lib/server/integrations/mailchimp.js +++ b/packages/vulcan-newsletter/lib/server/integrations/mailchimp.js @@ -6,6 +6,7 @@ import moment from 'moment'; import { getSetting } from 'meteor/vulcan:core'; import Newsletters from '../../modules/collection.js'; import MailChimpNPM from 'mailchimp'; +import { createError } from 'apollo-errors'; /* @@ -46,11 +47,18 @@ if (settings) { const subscribe = callSyncAPI('lists', 'subscribe', subscribeOptions); return {result: 'subscribed', ...subscribe}; } catch (error) { - // if the email is already in the Mailchimp list, no need to throw an error - if (error.message === "214") { - return {result: 'already-subscribed'}; + console.log(error) + let name, message; + if (error.code == 212) { + name = 'has_unsubscribed'; + } else if (error.code == 214) { + name = 'already_subscribed'; + } else { + name = 'subscription_failed'; + message = error.message; } - throw new Error("subscription-failed", error.message); + const NewsletterError = createError(name, { message }); + throw new NewsletterError(); } }, @@ -81,7 +89,8 @@ if (settings) { list_id: listId, subject: subject, from_email: fromEmail, - from_name: fromName + from_name: fromName, + timewarp: true // NOTE: Sidebar only }, content: { html: html, @@ -95,7 +104,8 @@ if (settings) { console.log('// Newsletter created'); // console.log(campaign) - const scheduledMoment = moment().utcOffset(0).add(1, 'hours'); + // NOTE: Sidebar only, schedule for next day at 9 AM + const scheduledMoment = moment().add(1, 'day').startOf('day').hour(9); const scheduledTime = scheduledMoment.format("YYYY-MM-DD HH:mm:ss"); const scheduleOptions = { diff --git a/packages/vulcan-newsletter/lib/server/mutations.js b/packages/vulcan-newsletter/lib/server/mutations.js index b6fdd698d..d9060eebc 100644 --- a/packages/vulcan-newsletter/lib/server/mutations.js +++ b/packages/vulcan-newsletter/lib/server/mutations.js @@ -28,20 +28,11 @@ const resolver = { if (!user || !Users.options.mutations.edit.check(currentUser, user)) { throw new Error(Utils.encodeIntlError({id: "app.noPermission"})); } - try { - return Newsletters.subscribeUser(user, false); - } catch (error) { - const errorMessage = error.message.includes('subscription-failed') ? Utils.encodeIntlError({id: "newsletter.subscription_failed"}) : error.message - throw new Error(errorMessage); - } + return Newsletters.subscribeUser(user, false); }, addEmailNewsletter(root, {email}, context) { - try { - return Newsletters.subscribeEmail(email, true); - } catch (error) { - const errorMessage = error.message.includes('subscription-failed') ? Utils.encodeIntlError({id: "newsletter.subscription_failed"}) : error.message - throw new Error(errorMessage); } + return Newsletters.subscribeEmail(email, true); }, removeUserNewsletter(root, { userId }, context) { const currentUser = context.currentUser;