heml icon indicating copy to clipboard operation
heml copied to clipboard

Meta errors when rendering multiple times concurrently

Open BenMansley opened this issue 5 years ago • 7 comments

Version: 1.1.3

Our company have recently converted all our emails to heml, and have been loving its simplicity so far. All of the emails we've sent so far have been transactional, where we've only sent them one at a time, and it's worked without a hitch. We're now implementing a monthly report for our users which will be sent out in bulk, and we're seeing errors in development.

The error trace is as follows:

TypeError: null is not iterable!
    at module.exports.require.getIterator (/Users/admin/Documents/backend/node_modules/core-js/library/modules/core.get-iterator.js:5:42)
    at Object.flush (/Users/admin/Documents/backend/node_modules/@heml/elements/build/Meta.js:60:54)
    at _callee$ (/Users/admin/Documents/backend/node_modules/@heml/render/build/index.js:343:73)
    at tryCatch (/Users/admin/Documents/backend/node_modules/regenerator-runtime/runtime.js:62:40)
    at Generator.invoke [as _invoke] (/Users/admin/Documents/backend/node_modules/regenerator-runtime/runtime.js:296:22)
    at Generator.prototype.(anonymous function) [as next] (/Users/admin/Documents/backend/node_modules/regenerator-runtime/runtime.js:114:21)
    at step (/Users/admin/Documents/backend/node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
    at /Users/admin/Documents/backend/node_modules/babel-runtime/helpers/asyncToGenerator.js:28:13

This seems to be caused by Meta - the metaMap Map is being flushed on the first render (this line), then the null Map is causing errors in subsequent renders.

Is there a preferred method to handle rendering multiple emails concurrently, or is this a bug? Happy to provide any more information if required - otherwise I suppose the quickest fix for us would be to build the emails in series.

Thanks, Ben Mansley

BenMansley avatar Mar 18 '19 14:03 BenMansley

Hello, Got exactly the same problems when rendering emails to send to different customers in AWS lambda

GemN avatar Jul 08 '19 09:07 GemN

@BenMansley @GemN or anyone find a solution to this? Same problem. It pretty much renders this project useless for service type activity :(

robmcfeely avatar Sep 26 '19 12:09 robmcfeely

I'm getting the same error. Has anybody found a solution or a workaround 😄 ? @BenMansley @GemN @robmcfeely

Devessier avatar Feb 10 '20 18:02 Devessier

Nope. We dropped the library

On Mon 10 Feb 2020, 18:46 Devessier, [email protected] wrote:

I'm getting the same error. Has anybody found a solution or a workaround 😄 ? @BenMansley https://github.com/BenMansley @GemN https://github.com/GemN @robmcfeely https://github.com/robmcfeely

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/SparkPost/heml/issues/91?email_source=notifications&email_token=AAZTJCSYPPHJGCHNOV45FNTRCGOJDA5CNFSM4G7H7LA2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOELJY5RI#issuecomment-584289989, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAZTJCSU4EP72DRMT2UI77DRCGOJDANCNFSM4G7H7LAQ .

robmcfeely avatar Feb 10 '20 19:02 robmcfeely

@robmcfeely Okay, thank your for your reply ! 👍

Devessier avatar Feb 10 '20 21:02 Devessier

I found a workaround. I actually build with a script all my folder heml, into a folder html. Push both folders and in the code I directly load from the html folder (and for variables i use Mustache)

Script to build:

#!/bin/bash
type heml >/dev/null 2>&1 || { echo >&2 "Require heml. Please install (yarn global add heml)."; exit 1; }

for entry in "heml"/*
do
  if [ -f "$entry" ];then
    echo "-- Building $entry to html"
    filename=${entry##*/}
    heml build $entry --output html/${filename%.*}.html
  fi
done

Load html email:

const htmlEmail = fs.readFileSync(`${__dirname}/../emails/templates/html/myemail.html`, {
  encoding: 'utf-8',
});

Build the emails with dynamic variables:

const htmlEmailWithValues = Mustache.render(htmlEmail, emailData);
const form = new FormData();
form.append('from', 'App <[email protected]>');
form.append('to', `${firstname} <${email}>`);
form.append('subject', subject);
form.append('html', htmlEmailWithValues);

GemN avatar Feb 11 '20 15:02 GemN

@GemN Great workaround !

I think I would have used your solution if I wouldn't must dynamically generate content using loops or conditions. I created a small class that spawns 4 Node.js thread workers, each of them executing the heml function while waiting for the previous execution to be completed in order to prevent race conditions we encountered. Like that I don't need to rely on HEML CLI.

The Gist containing the code : https://gist.github.com/Devessier/f17c3bf4e7f9a799059d1fec110ba841

Devessier avatar Feb 11 '20 15:02 Devessier