Skip to content

Commit 5b1898a

Browse files
theorchoosteren
authored andcommitted
Added ability to use custom function for error reporting instead built-in sendErrorPayload (#71)
* add custom reporting function * update readme
1 parent 97483e8 commit 5b1898a

3 files changed

Lines changed: 67 additions & 6 deletions

File tree

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,23 @@ errorHandler.start({
158158

159159
where `targetUrl` is the url you'd like to send errors to and can be relative or absolute. This endpoint will need to support the [Report API endpoint](https://cloud.google.com/error-reporting/reference/rest/v1beta1/projects.events/report).
160160

161+
## Custom message dispatching
162+
163+
If you can't use HTTP Post requests for reporting your errors, or in need for some more complicated customizations, you may provide a custom function to handle the reporting.
164+
165+
The function will be called with a payload argument (the same one that would have been sent on the HTTP Post request) and should return a Promise.
166+
167+
```javascript
168+
const errorHandler = new StackdriverErrorReporter();
169+
function myCustomFunction(payload) {
170+
console.log("custom reporting function called with payload:", payload);
171+
return Promise.resolve();
172+
}
173+
errorHandler.start({
174+
customReportingFunction: myCustomFunction,
175+
});
176+
```
177+
161178
## Best Practices
162179

163180
### Only reporting in the production environment with Webpack

stackdriver-errors.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,21 @@ var StackdriverErrorReporter = function() {};
3333
* @param {string} [config.context.user] - the user who caused or was affected by the error.
3434
* @param {String} config.key - the API key to use to call the API.
3535
* @param {String} config.projectId - the Google Cloud Platform project ID to report errors to.
36+
* @param {Function} config.customReportingFunction - Custom function to be called with the error payload for reporting, instead of HTTP request. The function should return a Promise.
3637
* @param {String} [config.service=web] - service identifier.
3738
* @param {String} [config.version] - version identifier.
3839
* @param {Boolean} [config.reportUncaughtExceptions=true] - Set to false to stop reporting unhandled exceptions.
3940
* @param {Boolean} [config.disabled=false] - Set to true to not report errors when calling report(), this can be used when developping locally.
4041
*/
4142
StackdriverErrorReporter.prototype.start = function(config) {
42-
if (!config.key && !config.targetUrl) {
43-
throw new Error('Cannot initialize: No API key or target url provided.');
43+
if (!config.key && !config.targetUrl && !config.customReportingFunction) {
44+
throw new Error('Cannot initialize: No API key, target url or custom reporting function provided.');
4445
}
45-
if (!config.projectId && !config.targetUrl) {
46-
throw new Error('Cannot initialize: No project ID or target url provided.');
46+
if (!config.projectId && !config.targetUrl && !config.customReportingFunction) {
47+
throw new Error('Cannot initialize: No project ID, target url or custom reporting function provided.');
4748
}
4849

50+
this.customReportingFunction = config.customReportingFunction;
4951
this.apiKey = config.key;
5052
this.projectId = config.projectId;
5153
this.targetUrl = config.targetUrl;
@@ -127,9 +129,14 @@ StackdriverErrorReporter.prototype.report = function(err, options) {
127129
var reportUrl = this.targetUrl || (
128130
baseAPIUrl + this.projectId + '/events:report?key=' + this.apiKey);
129131

132+
var customFunc = this.customReportingFunction;
133+
130134
return resolveError(err, firstFrameIndex)
131135
.then(function(message) {
132136
payload.message = message;
137+
if (customFunc) {
138+
return customFunc(payload);
139+
}
133140
return sendErrorPayload(reportUrl, payload);
134141
});
135142
};

test/test.js

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ function expectRequestWithMessage(message) {
3131
expect(sentBody.message).to.contain(message);
3232
}
3333

34+
/**
35+
* Helper function testing if a given message has been reported inside a payload
36+
* @param {string} [payload] - payload
37+
* @param {string} [message] - Substring that message must contain.
38+
*/
39+
function expectPayloadWithMessage(payload, message) {
40+
var sentBody = payload;
41+
expect(sentBody).to.include.keys('message');
42+
expect(sentBody.message).to.contain(message);
43+
}
44+
3445
/**
3546
* Helper for testing call stack reporting
3647
* @param {string} [message] - Contents of error to throw.
@@ -81,13 +92,13 @@ describe('Initialization', function() {
8192
expect(errorHandler.reportUnhandledPromiseRejections).to.equal(true);
8293
});
8394

84-
it('should fail if no API key or custom url', function() {
95+
it('should fail if no API key or custom url or custom func', function() {
8596
expect(function() {
8697
errorHandler.start({projectId: 'projectId'});
8798
}).to.throw(Error, /API/);
8899
});
89100

90-
it('should fail if no project ID or custom url', function() {
101+
it('should fail if no project ID or custom url or custom func', function() {
91102
expect(function() {
92103
errorHandler.start({key: 'key'});
93104
}).to.throw(Error, /project/);
@@ -99,6 +110,15 @@ describe('Initialization', function() {
99110
}).to.not.throw();
100111
});
101112

113+
it('should succeed if custom function provided without API key or project id', function() {
114+
expect(function() {
115+
function f() {
116+
117+
}
118+
errorHandler.start({customReportingFunction: f});
119+
}).to.not.throw();
120+
});
121+
102122
it('should have default context', function() {
103123
errorHandler.start({key: 'key', projectId: 'projectId'});
104124
expect(errorHandler.context).to.eql({});
@@ -244,6 +264,23 @@ describe('Reporting errors', function() {
244264
});
245265
});
246266
});
267+
268+
describe('Custom reporting function', function() {
269+
it('should report error messages only to custom function', function() {
270+
var funcResult = null;
271+
function customFunc(payload) {
272+
funcResult = payload;
273+
return Promise.resolve();
274+
}
275+
errorHandler.start({customReportingFunction: customFunc});
276+
277+
var message = 'Something broke!';
278+
return errorHandler.report(message).then(function() {
279+
expectPayloadWithMessage(funcResult, message);
280+
expect(requests.length).to.equal(0);
281+
});
282+
});
283+
});
247284
});
248285

249286
describe('Unhandled exceptions', function() {

0 commit comments

Comments
 (0)