diff --git a/src/publisher/index.ts b/src/publisher/index.ts index ef169e086..3378e16a4 100644 --- a/src/publisher/index.ts +++ b/src/publisher/index.ts @@ -154,11 +154,21 @@ export class Publisher { publishMessage(message: PubsubMessage, callback: PublishCallback): void { const {data, attributes = {}} = message; - if (!(data instanceof Buffer)) { + // We must have at least one of: + // - `data` as a Buffer + // - `attributes` that are not empty + if (data && !(data instanceof Buffer)) { throw new TypeError('Data must be in the form of a Buffer.'); } - for (const key of Object.keys(attributes!)) { + const keys = Object.keys(attributes!); + if (!data && keys.length === 0) { + throw new TypeError( + 'If data is undefined, at least one attribute must be present.' + ); + } + + for (const key of keys) { const value = attributes![key]; if (typeof value !== 'string') { throw new TypeError(`All attributes must be in the form of a string. diff --git a/test/publisher/index.ts b/test/publisher/index.ts index 4d410e0ea..04319b8e5 100644 --- a/test/publisher/index.ts +++ b/test/publisher/index.ts @@ -243,6 +243,18 @@ describe('Publisher', () => { ); }); + it('should throw an error if data and attributes are both empty', () => { + assert.throws( + () => publisher.publishMessage({}, spy), + /at least one attribute must be present/ + ); + }); + + it('should allow sending only attributes', () => { + const attributes = {foo: 'bar'} as {}; + assert.doesNotThrow(() => publisher.publishMessage({attributes}, spy)); + }); + it('should throw an error if attributes are wrong format', () => { const attributes = {foo: {bar: 'baz'}} as {};