diff --git a/.changeset/fix-relay-connect-error.md b/.changeset/fix-relay-connect-error.md new file mode 100644 index 0000000..a197def --- /dev/null +++ b/.changeset/fix-relay-connect-error.md @@ -0,0 +1,9 @@ +--- +'@maildev/smtp': patch +'maildev': patch +--- + +Fail the relay when the outgoing server cannot be reached. The connection +error was only logged, so the relay never finished: with auto-relay on, the +SMTP client sending to MailDev never got its reply, and the manual relay +request never answered. diff --git a/packages/smtp/src/__tests__/relay.test.ts b/packages/smtp/src/__tests__/relay.test.ts index 1e0a2ff..89f1e97 100644 --- a/packages/smtp/src/__tests__/relay.test.ts +++ b/packages/smtp/src/__tests__/relay.test.ts @@ -147,6 +147,17 @@ describe('relay raw email stream', () => { expect(stream.destroyed).toBe(true) }) + it('closes the stream when the outgoing server cannot be reached', async () => { + const client = new RelayClient({ host: '127.0.0.1', port: await freePort() }, false) + const stream = createReadStream(emlPath) + + const result = await client.relay(email, stream) + + expect(result.success).toBe(false) + expect(result.error).toBeInstanceOf(Error) + expect(stream.destroyed).toBe(true) + }) + it('closes the stream when the outgoing server rejects the recipient', async () => { const port = await freePort() const rejecting = new SMTPServerLib({ diff --git a/packages/smtp/src/relay.ts b/packages/smtp/src/relay.ts index fcb982e..2cd9f33 100644 --- a/packages/smtp/src/relay.ts +++ b/packages/smtp/src/relay.ts @@ -160,8 +160,10 @@ export class RelayClient { debug: false, }) + // A failed connection is reported here, not through the connect callback this.client.on('error', (err: Error) => { this.logger.error('SMTP Connection error:', err) + reject(err) }) this.client.connect((err?: Error) => {