Skip to content

Commit c3da5af

Browse files
authored
Merge pull request #9 from GraphQLCollege/error-messages
Improve error messages
2 parents 86a8bd6 + bc99ad7 commit c3da5af

File tree

4 files changed

+72
-37
lines changed

4 files changed

+72
-37
lines changed

README.md

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ Afterwards replace `PubSub` with `PostgresPubSub`:
2020

2121
```js
2222
// Before
23-
import { PubSub } from 'graphql-subscriptions';
23+
import { PubSub } from "graphql-subscriptions";
2424

2525
export const pubsub = new PubSub();
2626
```
2727

2828
```js
2929
// After
30-
import { PostgresPubSub } from 'graphql-postgres-subscriptions';
30+
import { PostgresPubSub } from "graphql-postgres-subscriptions";
3131

3232
export const pubsub = new PostgresPubSub();
3333
```
@@ -43,7 +43,7 @@ You can also pass [node-postgres connection options](https://node-postgres.com/f
4343
You can instantiate your own `client` and pass it to `PostgresPubSub`. Like this:
4444

4545
```js
46-
import { PostgresPubSub } from 'graphql-postgres-subscriptions';
46+
import { PostgresPubSub } from "graphql-postgres-subscriptions";
4747
import { Client } from "pg";
4848

4949
const client = new Client();
@@ -53,11 +53,29 @@ const pubsub = new PostgresPubSub({ client });
5353

5454
**Important**: Don't pass clients from `pg`'s `Pool` to `PostgresPubSub`. As [node-postgres creator states in this StackOverflow answer](https://stackoverflow.com/questions/8484404/what-is-the-proper-way-to-use-the-node-js-postgresql-module), the client needs to be around and not shared so pg can properly handle `NOTIFY` messages (which this library uses under the hood)
5555

56+
## Error handling
57+
58+
`PostgresPubSub` instances emit a special event called `"error"`. This event's payload is an instance of Javascript's `Error`. You can get the error's text using `error.message`.
59+
60+
```js
61+
const ps = new PostgresPubSub({ client });
62+
63+
ps.subscribe("error", err => {
64+
console.log(err.message); // -> "payload string too long"
65+
}).then(() => ps.publish("a", "a".repeat(9000)));
66+
```
67+
68+
For example you can log all error messages (including stack traces and friends) using something like this:
69+
70+
```js
71+
ps.subscribe("error", console.error);
72+
```
73+
5674
## Development
5775

5876
This project has an integration test suite that uses [`jest`](https://facebook.github.io/jest/) to make sure everything works correctly.
5977

6078
We use Docker to spin up a PostgreSQL instance before running the tests. To run them, type the following commands:
6179

62-
* `docker-compose build`
63-
* `docker-compose run test`
80+
- `docker-compose build`
81+
- `docker-compose run test`

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "graphql-postgres-subscriptions",
3-
"version": "1.0.2",
3+
"version": "1.0.3",
44
"main": "index.js",
55
"license": "MIT",
66
"engines": {

postgres-pubsub.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ class PostgresPubSub extends PubSub {
2121
return true;
2222
}
2323
subscribe(triggerName, onMessage) {
24-
const callback = ({ payload }) => onMessage(payload);
24+
const callback = message => {
25+
onMessage(message instanceof Error ? message : message.payload);
26+
};
2527
this.ee.on(triggerName, callback);
2628
this.subIdCounter = this.subIdCounter + 1;
2729
this.subscriptions[this.subIdCounter] = [triggerName, callback];

postgres-pubsub.test.js

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,36 +14,36 @@ describe("PostgresPubSub", () => {
1414
test("PostgresPubSub can subscribe when instantiated without a client", function(done) {
1515
const ps = new PostgresPubSub();
1616
ps.subscribe("a", payload => {
17-
expect(payload).toEqual("test");
18-
done();
17+
expect(payload).toEqual("test");
18+
done();
1919
}).then(() => {
20-
const succeed = ps.publish("a", "test");
21-
expect(succeed).toBe(true);
22-
});
20+
const succeed = ps.publish("a", "test");
21+
expect(succeed).toBe(true);
22+
});
2323
});
2424

2525
test("PostgresPubSub can subscribe and is called when events happen", function(done) {
2626
const ps = new PostgresPubSub({ client });
2727
ps.subscribe("a", payload => {
28-
expect(payload).toEqual("test");
29-
done();
28+
expect(payload).toEqual("test");
29+
done();
3030
}).then(() => {
31-
const succeed = ps.publish("a", "test");
32-
expect(succeed).toBe(true);
33-
});
31+
const succeed = ps.publish("a", "test");
32+
expect(succeed).toBe(true);
33+
});
3434
});
3535

3636
test("PostgresPubSub can subscribe when instantiated with connection options but without a client", function(done) {
3737
const ps = new PostgresPubSub({
3838
connectionString: process.env.DATABASE_URL
3939
});
4040
ps.subscribe("a", payload => {
41-
expect(payload).toEqual("test");
42-
done();
41+
expect(payload).toEqual("test");
42+
done();
4343
}).then(() => {
44-
const succeed = ps.publish("a", "test");
45-
expect(succeed).toBe(true);
46-
});
44+
const succeed = ps.publish("a", "test");
45+
expect(succeed).toBe(true);
46+
});
4747
});
4848

4949
test("should send notification event after calling publish", done => {
@@ -53,24 +53,39 @@ describe("PostgresPubSub", () => {
5353
done();
5454
});
5555
ps.subscribe("a", payload => {
56-
expect(payload).toEqual("test");
56+
expect(payload).toEqual("test");
5757
}).then(() => {
58-
const succeed = ps.publish("a", "test");
59-
expect(succeed).toBe(true);
60-
});
58+
const succeed = ps.publish("a", "test");
59+
expect(succeed).toBe(true);
60+
});
6161
});
6262

6363
test("PostgresPubSub can unsubscribe", function(done) {
6464
const ps = new PostgresPubSub({ client });
6565
ps.subscribe("a", payload => {
66-
expect(false).toBe(true); // Should not reach this point
66+
expect(false).toBe(true); // Should not reach this point
6767
}).then(subId => {
68-
ps.unsubscribe(subId);
69-
const succeed = ps.publish("a", "test");
70-
expect(succeed).toBe(true); // True because publish success is not
71-
// indicated by trigger having subscriptions
72-
done(); // works because pubsub is synchronous
73-
});
68+
ps.unsubscribe(subId);
69+
const succeed = ps.publish("a", "test");
70+
expect(succeed).toBe(true); // True because publish success is not
71+
// indicated by trigger having subscriptions
72+
done(); // works because pubsub is synchronous
73+
});
74+
});
75+
76+
test("Should emit error when payload exceeds Postgres 8000 character limit", done => {
77+
const ps = new PostgresPubSub({ client });
78+
ps.subscribe("a", () => {
79+
expect(false).toBe(true); // Should not reach this point
80+
done();
81+
});
82+
ps.subscribe("error", err => {
83+
expect(err.message).toEqual("payload string too long");
84+
done();
85+
}).then(() => {
86+
const succeed = ps.publish("a", "a".repeat(9000));
87+
expect(succeed).toBe(true);
88+
});
7489
});
7590

7691
test("AsyncIterator should expose valid asyncIterator for a specific event", () => {
@@ -130,10 +145,10 @@ describe("PostgresPubSub", () => {
130145
iterator
131146
.next()
132147
.then(result => {
133-
expect(result).not.toBeUndefined();
134-
expect(result.value).not.toBeUndefined();
135-
expect(result.done).toBe(false);
136-
});
148+
expect(result).not.toBeUndefined();
149+
expect(result.value).not.toBeUndefined();
150+
expect(result.done).toBe(false);
151+
});
137152

138153
ps.publish(eventName, { test: true });
139154

0 commit comments

Comments
 (0)