Skip to content

Commit 8ba8a33

Browse files
committed
Removes second log when responding with a regular error
1 parent b9673da commit 8ba8a33

File tree

4 files changed

+47
-31
lines changed

4 files changed

+47
-31
lines changed

spec/CloudCodeLogger.spec.js

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const LoggerController = require('../lib/Controllers/LoggerController').LoggerController;
22
const WinstonLoggerAdapter = require('../lib/Adapters/Logger/WinstonLoggerAdapter').WinstonLoggerAdapter;
33
const fs = require('fs');
4+
const Config = require('../lib/Config');
45

56
const loremFile = __dirname + '/support/lorem.txt';
67

@@ -23,34 +24,33 @@ describe("Cloud Code Logger", () => {
2324
// Note that helpers takes care of logout.
2425
// see helpers.js:afterEach
2526

26-
it("should expose log to functions", done => {
27-
const logController = new LoggerController(new WinstonLoggerAdapter());
27+
it("should expose log to functions", () => {
28+
const config = Config.get('test');
29+
const spy = spyOn(config.loggerController, 'log').and.callThrough();
2830

2931
Parse.Cloud.define("loggerTest", (req, res) => {
3032
req.log.info('logTest', 'info log', { info: 'some log' });
3133
req.log.error('logTest', 'error log', { error: 'there was an error' });
3234
res.success({});
3335
});
3436

35-
Parse.Cloud.run('loggerTest').then(() => {
36-
return logController.getLogs({ from: Date.now() - 500, size: 1000 });
37-
}).then((res) => {
38-
expect(res.length).not.toBe(0);
39-
const lastLogs = res.slice(0, 3);
40-
const cloudFunctionMessage = lastLogs[0];
41-
const errorMessage = lastLogs[1];
42-
const infoMessage = lastLogs[2];
43-
expect(cloudFunctionMessage.level).toBe('info');
44-
expect(cloudFunctionMessage.params).toEqual({});
45-
expect(cloudFunctionMessage.message).toMatch(/Ran cloud function loggerTest for user [^ ]* with:\n {2}Input: {}\n {2}Result: {}/);
46-
expect(cloudFunctionMessage.functionName).toEqual('loggerTest');
47-
expect(errorMessage.level).toBe('error');
48-
expect(errorMessage.error).toBe('there was an error');
49-
expect(errorMessage.message).toBe('logTest error log');
50-
expect(infoMessage.level).toBe('info');
51-
expect(infoMessage.info).toBe('some log');
52-
expect(infoMessage.message).toBe('logTest info log');
53-
done();
37+
return Parse.Cloud.run('loggerTest').then(() => {
38+
expect(spy).toHaveBeenCalledTimes(3);
39+
const cloudFunctionMessage = spy.calls.all()[2];
40+
const errorMessage = spy.calls.all()[1];
41+
const infoMessage = spy.calls.all()[0];
42+
expect(cloudFunctionMessage.args[0]).toBe('info');
43+
expect(cloudFunctionMessage.args[1][1].params).toEqual({});
44+
expect(cloudFunctionMessage.args[1][0]).toMatch(/Ran cloud function loggerTest for user [^ ]* with:\n {2}Input: {}\n {2}Result: {}/);
45+
expect(cloudFunctionMessage.args[1][1].functionName).toEqual('loggerTest');
46+
expect(errorMessage.args[0]).toBe('error');
47+
expect(errorMessage.args[1][2].error).toBe('there was an error');
48+
expect(errorMessage.args[1][0]).toBe('logTest');
49+
expect(errorMessage.args[1][1]).toBe('error log');
50+
expect(infoMessage.args[0]).toBe('info');
51+
expect(infoMessage.args[1][2].info).toBe('some log');
52+
expect(infoMessage.args[1][0]).toBe('logTest');
53+
expect(infoMessage.args[1][1]).toBe('info log');
5454
});
5555
});
5656

@@ -194,7 +194,8 @@ describe("Cloud Code Logger", () => {
194194
Parse.Cloud.run('aFunction', { foo: 'bar' })
195195
.then(null, () => logController.getLogs({ from: Date.now() - 500, size: 1000 }))
196196
.then(logs => {
197-
const log = logs[2];
197+
expect(logs[0].message).toBe('it failed!');
198+
const log = logs[1];
198199
expect(log.level).toEqual('error');
199200
expect(log.message).toMatch(
200201
/Failed running cloud function aFunction for user [^ ]* with:\n {2}Input: {"foo":"bar"}\n {2}Error: {"code":141,"message":"it failed!"}/);
@@ -243,4 +244,18 @@ describe("Cloud Code Logger", () => {
243244
})
244245
.then(null, e => done.fail(e));
245246
});
247+
248+
it('should only log once for object not found', async () => {
249+
const config = Config.get('test');
250+
const spy = spyOn(config.loggerController, 'error').and.callThrough();
251+
try {
252+
const object = new Parse.Object('Object');
253+
object.id = 'invalid'
254+
await object.fetch();
255+
} catch(e) { /**/ }
256+
expect(spy).toHaveBeenCalled();
257+
expect(spy.calls.count()).toBe(1);
258+
const { args } = spy.calls.mostRecent();
259+
expect(args[0]).toBe('Object not found.');
260+
});
246261
});

spec/LogsRouter.spec.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ describe('LogsRouter', () => {
8787
}, (error, response, body) => {
8888
expect(response.statusCode).toEqual(200);
8989
// 4th entry is our actual GET request
90-
expect(body[3].url).toEqual('/1/login?username=test&password=********');
91-
expect(body[3].message).toEqual('REQUEST for [GET] /1/login?username=test&password=********: {}');
90+
expect(body[2].url).toEqual('/1/login?username=test&password=********');
91+
expect(body[2].message).toEqual('REQUEST for [GET] /1/login?username=test&password=********: {}');
9292
done();
9393
});
9494
});
@@ -114,8 +114,8 @@ describe('LogsRouter', () => {
114114
}, (error, response, body) => {
115115
expect(response.statusCode).toEqual(200);
116116
// 4th entry is our actual GET request
117-
expect(body[3].url).toEqual('/1/login?username=test&password=********');
118-
expect(body[3].message).toEqual('REQUEST for [GET] /1/login?username=test&password=********: {}');
117+
expect(body[2].url).toEqual('/1/login?username=test&password=********');
118+
expect(body[2].message).toEqual('REQUEST for [GET] /1/login?username=test&password=********: {}');
119119
done();
120120
});
121121
});
@@ -144,8 +144,8 @@ describe('LogsRouter', () => {
144144
}, (error, response, body) => {
145145
expect(response.statusCode).toEqual(200);
146146
// 4th entry is our actual GET request
147-
expect(body[3].url).toEqual('/1/login');
148-
expect(body[3].message).toEqual('REQUEST for [POST] /1/login: {}');
147+
expect(body[2].url).toEqual('/1/login');
148+
expect(body[2].message).toEqual('REQUEST for [POST] /1/login: {}');
149149
done();
150150
});
151151
});

src/PromiseRouter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ function makeExpressHandler(appId, promiseHandler) {
181181
})
182182
}
183183
res.json(result.response);
184-
}, (e) => {
184+
}, (error) => next(error)).catch((e) => {
185185
log.error(`Error generating response. ${inspect(e)}`, {error: e});
186186
next(e);
187187
});

src/middlewares.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import AppCache from './cache';
2-
import log from './logger';
32
import Parse from 'parse/node';
43
import auth from './Auth';
54
import Config from './Config';
65
import ClientSDK from './ClientSDK';
6+
import defaultLogger from './logger';
77

88
// Checks that the request is authorized for this app and checks user
99
// auth too.
@@ -179,7 +179,7 @@ export function handleParseHeaders(req, res, next) {
179179
}
180180
else {
181181
// TODO: Determine the correct error scenario.
182-
log.error('error getting auth for sessionToken', error);
182+
req.config.loggerController.error('error getting auth for sessionToken', error);
183183
throw new Parse.Error(Parse.Error.UNKNOWN_ERROR, error);
184184
}
185185
});
@@ -267,6 +267,7 @@ export function allowMethodOverride(req, res, next) {
267267
}
268268

269269
export function handleParseErrors(err, req, res, next) {
270+
const log = (req.config && req.config.loggerController) || defaultLogger;
270271
if (err instanceof Parse.Error) {
271272
let httpStatus;
272273
// TODO: fill out this mapping

0 commit comments

Comments
 (0)