Skip to content

Commit

Permalink
Added ability to use custom function for error reporting instead buil…
Browse files Browse the repository at this point in the history
…t-in sendErrorPayload (#71)

* add custom reporting function

* update readme
  • Loading branch information
theorchoo authored and steren committed Dec 26, 2019
1 parent 97483e8 commit 5b1898a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 6 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,23 @@ errorHandler.start({

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).

## Custom message dispatching

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.

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.

```javascript
const errorHandler = new StackdriverErrorReporter();
function myCustomFunction(payload) {
console.log("custom reporting function called with payload:", payload);
return Promise.resolve();
}
errorHandler.start({
customReportingFunction: myCustomFunction,
});
```

## Best Practices

### Only reporting in the production environment with Webpack
Expand Down
15 changes: 11 additions & 4 deletions stackdriver-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,21 @@ var StackdriverErrorReporter = function() {};
* @param {string} [config.context.user] - the user who caused or was affected by the error.
* @param {String} config.key - the API key to use to call the API.
* @param {String} config.projectId - the Google Cloud Platform project ID to report errors to.
* @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.
* @param {String} [config.service=web] - service identifier.
* @param {String} [config.version] - version identifier.
* @param {Boolean} [config.reportUncaughtExceptions=true] - Set to false to stop reporting unhandled exceptions.
* @param {Boolean} [config.disabled=false] - Set to true to not report errors when calling report(), this can be used when developping locally.
*/
StackdriverErrorReporter.prototype.start = function(config) {
if (!config.key && !config.targetUrl) {
throw new Error('Cannot initialize: No API key or target url provided.');
if (!config.key && !config.targetUrl && !config.customReportingFunction) {
throw new Error('Cannot initialize: No API key, target url or custom reporting function provided.');
}
if (!config.projectId && !config.targetUrl) {
throw new Error('Cannot initialize: No project ID or target url provided.');
if (!config.projectId && !config.targetUrl && !config.customReportingFunction) {
throw new Error('Cannot initialize: No project ID, target url or custom reporting function provided.');
}

this.customReportingFunction = config.customReportingFunction;
this.apiKey = config.key;
this.projectId = config.projectId;
this.targetUrl = config.targetUrl;
Expand Down Expand Up @@ -127,9 +129,14 @@ StackdriverErrorReporter.prototype.report = function(err, options) {
var reportUrl = this.targetUrl || (
baseAPIUrl + this.projectId + '/events:report?key=' + this.apiKey);

var customFunc = this.customReportingFunction;

return resolveError(err, firstFrameIndex)
.then(function(message) {
payload.message = message;
if (customFunc) {
return customFunc(payload);
}
return sendErrorPayload(reportUrl, payload);
});
};
Expand Down
41 changes: 39 additions & 2 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ function expectRequestWithMessage(message) {
expect(sentBody.message).to.contain(message);
}

/**
* Helper function testing if a given message has been reported inside a payload
* @param {string} [payload] - payload
* @param {string} [message] - Substring that message must contain.
*/
function expectPayloadWithMessage(payload, message) {
var sentBody = payload;
expect(sentBody).to.include.keys('message');
expect(sentBody.message).to.contain(message);
}

/**
* Helper for testing call stack reporting
* @param {string} [message] - Contents of error to throw.
Expand Down Expand Up @@ -81,13 +92,13 @@ describe('Initialization', function() {
expect(errorHandler.reportUnhandledPromiseRejections).to.equal(true);
});

it('should fail if no API key or custom url', function() {
it('should fail if no API key or custom url or custom func', function() {
expect(function() {
errorHandler.start({projectId: 'projectId'});
}).to.throw(Error, /API/);
});

it('should fail if no project ID or custom url', function() {
it('should fail if no project ID or custom url or custom func', function() {
expect(function() {
errorHandler.start({key: 'key'});
}).to.throw(Error, /project/);
Expand All @@ -99,6 +110,15 @@ describe('Initialization', function() {
}).to.not.throw();
});

it('should succeed if custom function provided without API key or project id', function() {
expect(function() {
function f() {

}
errorHandler.start({customReportingFunction: f});
}).to.not.throw();
});

it('should have default context', function() {
errorHandler.start({key: 'key', projectId: 'projectId'});
expect(errorHandler.context).to.eql({});
Expand Down Expand Up @@ -244,6 +264,23 @@ describe('Reporting errors', function() {
});
});
});

describe('Custom reporting function', function() {
it('should report error messages only to custom function', function() {
var funcResult = null;
function customFunc(payload) {
funcResult = payload;
return Promise.resolve();
}
errorHandler.start({customReportingFunction: customFunc});

var message = 'Something broke!';
return errorHandler.report(message).then(function() {
expectPayloadWithMessage(funcResult, message);
expect(requests.length).to.equal(0);
});
});
});
});

describe('Unhandled exceptions', function() {
Expand Down

0 comments on commit 5b1898a

Please sign in to comment.