Note that there are some explanatory texts on larger screens.

plurals
  1. POError: write EPIPE at errnoException (net.js:770:11)
    text
    copied!<p>I have this system which attempts to send bulk emails written in NodeJS.</p> <p>It uses 2 modules: fs (build into node v0.8.18) and nodemailer (from NPM, v0.3.42).</p> <p>Now upon execution with <code>node newsletter.js</code> sometimes it will finish and complete, but sometimes it will randomly fail at a random point with the following error:</p> <pre><code>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) </code></pre> <p>As far as i understand the EPIPE error occurs because the other end of a connection dropped and then we tried to write to that connection. All existing reports of this EPIPE error bug are in the context of opening a http connection or similar.</p> <p>In what I have below the two things that could be causing the error is the <code>fs.readFileSync</code> in NewsletterEmail or the <code>mailer.send</code> in NewsleterMailer. Its more likely that the error would be in the mailer.send and nodemailer is opening a connection somewhere. However no error is being passed back up via a throw or callback error argument so there seems to be no way to see what is causing the error.</p> <p>Most people suggest defining a error handler. However there is nothing in nodemailer or the fs module which allows me to define a error handler. The callback in nodemailer from the <code>mailer.send</code> call does pass an error argument in its callback, however this particular error isn't coming through there.</p> <p>I have tried the following things:</p> <ul> <li>adding try/catch around both <code>fs.readFileSync</code> and the nodemailer transport sendEmail calls.</li> <li>Removing the fs.readFileSync calls and inlining the html - when i do this the error doesnt seem to occur. But again, the node docs have no indication that EPIPE errors should occur on readFileSync and there is certainly no way to add a error handler.</li> </ul> <p>The code which triggers this error is below:</p> <pre><code>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 &gt; 0) { sendEmail(); } else { mailer.close(); console.log('complete'); } }); } sendEmail(); } var nl = new Newsletter(); nl.send(); </code></pre> <p>Has anyone else come across similar errors? Do you have any tips for debugging or possible solutions.</p> <p>With the stack trace given im at a bit of a dead end with this now. Below is the output of strace. Seems to always die on that mail mimepart boundary first:</p> <pre><code>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, "&lt;!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) &amp;&amp; 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 </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload