Error: write EPIPE to errnoException (net.js: 770: 11)

I have this system that is trying to send bulk emails written in NodeJS.

It uses 2 modules: fs (built into node v0.8.18) and nodemailer (from NPM, v0.3.42).

Now, after executing with node newsletter.js sometimes it ends and ends, but sometimes it randomly breaks at a random point with the following error:

 stream.js:81 throw er; // Unhandled stream error in pipe. ^ Error: write EPIPE at errnoException (net.js:770:11) at Object.afterWrite (net.js:594:19) 

As far as I understand, the EPIPE error occurs because the other end of the connection went down, and then we tried to record this connection. All existing reports of this EPIPE error error are in the context of opening an http connection or the like.

What I have below two factors that can cause an error is fs.readFileSync in NewsletterEmail or mailer.send in NewsleterMailer. Most likely, the error will be in mailer.send and nodemailer, a connection is opened somewhere. However, no error is returned back through the throw or callback error argument, so there seems to be no way to see what causes the error.

Most people suggest defining an error handler. However, there is nothing in the nodemailer or the fs module that would allow me to define an error handler. The callback to nodemailer from the call to mailer.send passes the error argument to its callback, however this particular error does not go through it.

I have tried the following things:

  • adding try / catch in both fs.readFileSync and sendEmail calls to send nodemailer.
  • Removing fs.readFileSync calls and turning on html - when I do this, an error does not occur. But then again, node documents have no indication that EPIPE read errors should occur in readFileSync, and of course there is no way to add an error handler.

The code that causes this error is below:

 var nodemailer = require('nodemailer'); var fs = require('fs'); /** * Provides a way to build newsletters when given a folder containing * the relevant template and images in a standard format. This folder * must contain a newsletter.html file, a newsletter.txt file and a images * directory containing any images. * * @param {Object} settings The full folder path to the */ function NewsletterEmail(newsletterGroup, newsletterName) { var folder = '/var/newsletters/' + newsletterGroup + '/' + newsletterName; this._html = fs.readFileSync(folder + '/newsletter.html', 'utf-8'); this._text = fs.readFileSync(folder + '/newsletter.txt', 'utf-8'); } NewsletterEmail.prototype.getSubject = function() { return 'Testing'; } /** * Generates the HTML version of a newsletter. * * @return {String} */ NewsletterEmail.prototype.buildHTML = function(email) { var htmlPart = this._html; return htmlPart; } /** * Generates the text counterpart of a newsletter. * * @return {String} */ NewsletterEmail.prototype.buildText = function(email) { var textPart = this._text; return textPart; } /** * Creates a NewsletterEmail from the given folder. * * @param {String} folder The folder containing the html template, text template and images for a newsletter. * @return {NewsletterEmail} */ NewsletterEmail.create = function(newsleterGroup, newsletterName) { return new NewsletterEmail(newsleterGroup, newsletterName); } function NewsletterMailer(fromEmail) { this._from = fromEmail; this._transport = nodemailer.createTransport('sendmail'); } NewsletterMailer.prototype = { send: function(email, newsletterEmail, callback) { var mailOptions = { to: email, from: this._from, subject: newsletterEmail.getSubject(), html: newsletterEmail.buildHTML(email), text: newsletterEmail.buildText(email) }; this._transport.sendMail(mailOptions, callback); }, close: function() { this._transport.close(); } } function Newsletter() { this._id = 1; this.countSent = 0; this.emailsToSend = [' email1@example.com ', ' email2@example.com ', ' email3@example.com ', ' email4@example.com ', ' email5@example.com ', ' email6@example.com ']; } Newsletter.prototype.send = function() { var newsletter = this; var newsletterEmail = NewsletterEmail.create('company1', '2013-01-24-mynewsleter'); var mailer = new NewsletterMailer(' company@example.com '); function sendEmail() { var email = newsletter.emailsToSend.pop(); mailer.send(email, newsletterEmail, function(mailerErr) { if (mailerErr) { console.log('Mailer error: ', mailerErr); } newsletter.countSent++; console.log('progress ' + newsletter.countSent); if (newsletter.emailsToSend.length > 0) { sendEmail(); } else { mailer.close(); console.log('complete'); } }); } sendEmail(); } var nl = new Newsletter(); nl.send(); 

Does anyone else encounter similar errors? You have some debugging tips or possible solutions.

With the stack trace given by im at a standstill with this now. The following is the output of strace. It always seems to die on this mimepart mail border:

 futex(0x7f039c0008c8, FUTEX_WAKE_PRIVATE, 1) = 1 write(8, "------Nodemailer-0.3.42-?=_1-136"..., 131) = -1 EPIPE (Broken pipe) --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=13813, si_uid=0} --- --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=13818, si_status=0, si_utime=0, si_stime=0} --- write(4, "\1\0\0\0\0\0\0\0", 8) = 8 rt_sigreturn() = -1 EPIPE (Broken pipe) futex(0x7f039c0008c8, FUTEX_WAKE_PRIVATE, 1) = 1 write(8, "<!DOCTYPE HTML PUBLIC =22-//W3C/"..., 18098) = -1 EPIPE (Broken pipe) --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=13813, si_uid=0} --- futex(0x7f039c0008c8, FUTEX_WAKE_PRIVATE, 1) = 1 close(8) = 0 epoll_wait(3, {{EPOLLIN|EPOLLHUP, {u32=9, u64=4294967305}}, {EPOLLIN|EPOLLHUP, {u32=11, u64=4294967307}}, {EPOLLIN, {u32=4, u64=4294967300}}}, 64, 0) = 3 epoll_ctl(3, EPOLL_CTL_MOD, 9, {EPOLLIN, {u32=9, u64=4294967305}}) = 0 epoll_ctl(3, EPOLL_CTL_MOD, 11, {EPOLLIN, {u32=11, u64=4294967307}}) = 0 read(4, "\1\0\0\0\0\0\0\0", 8) = 8 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG|WSTOPPED|WCONTINUED, NULL) = 13818 ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7fff2d6f4340) = -1 EINVAL (Invalid argument) fstat(1, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0 write(1, "progress 1\n", 11progress 1 ) = 11 socketpair(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC, 0, [7, 8]) = 0 socketpair(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC, 0, [10, 12]) = 0 socketpair(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC, 0, [13, 14]) = 0 pipe2([15, 16], O_NONBLOCK|O_CLOEXEC) = 0 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f03a4b35a10) = 13820 close(16) = 0 poll([{fd=15, events=POLLIN|POLLHUP}], 1, -1) = 1 ([{fd=15, revents=POLLHUP}]) close(15) = 0 close(7) = 0 ioctl(8, FIONBIO, [1]) = 0 close(12) = 0 ioctl(10, FIONBIO, [1]) = 0 close(14) = 0 ioctl(13, FIONBIO, [1]) = 0 wait4(-1, 0x7fff2d6f529c, WNOHANG|WSTOPPED|WCONTINUED, NULL) = 0 futex(0x7f039c0008c8, FUTEX_WAKE_PRIVATE, 1) = 1 brk(0x932000) = 0x932000 read(11, "", 65536) = 0 close(11) = 0 read(9, "", 65536) = 0 futex(0x7f039c0008c8, FUTEX_WAKE_PRIVATE, 1) = 1 close(9) = 0 write(2, "\n", 1 ) = 1 write(2, "events.js:71\n", 13events.js:71 
+4
source share
1 answer

This was because the wrap modules of the nodemailer module have 75 characters. One line was exactly 76 characters with a dot at the end. This point was wrapped in its line.

For SMTP servers, the dot in the line itself means the end of the message, and the connection closes. This caused the connection to close prematurely, and subsequent recording did not work with an EPIPE error.

With the support of nodemailer, this is now fixed in release 0.3.43 by adding the hte -i flag to the sendmail call, which tells sendmail to allow single-point strings.

Further information is available here: https://github.com/andris9/Nodemailer/issues/141 .

+5
source

All Articles