Adds callback parameter to the log and other functions.#73
Adds callback parameter to the log and other functions.#73vilyapilya merged 8 commits intomasterfrom
log and other functions.#73Conversation
dchai76
left a comment
There was a problem hiding this comment.
This is going to take me some time to review, I'm going to start with just one comment
|
|
||
| if (opts) { | ||
| if (typeof opts === 'string') { | ||
| if (typeof opts === 'function') { |
There was a problem hiding this comment.
We seem to do this a lot and it seems to me like a terrible idea - it's confusing to me that we can let people send in a callback function as the opts param. Wouldn't it be preferable to require them to send in an empty/null opts and be explicit about what callback is than this?
There was a problem hiding this comment.
Didn't answer my question, but I really dislike this - let's keep each parameter as it's meant to be instead of pseudo-overloading.
There was a problem hiding this comment.
sorry I did not see your comments.
There was a problem hiding this comment.
@dchai76 I think it's arguable. On one hand the implementation of the code library becomes harder to read and maintain. On the other hand, usage of our code libraries becomes easier (you don't have to write your code likes this logger.log("my lolg", {}, (err) => {if err stdout)}); every time when you need to pass the cb to the log function. I think it's better to take the burden of readability on us than pass it on users.
There was a problem hiding this comment.
and besides, we can also pass a level to that. And it can grow into log("logline", "", {}, cb). Which I think is not a really good practice.
There was a problem hiding this comment.
To be clear, I think this is bad for callers, not for our own maintainability - magic overloading can mask errors on their part. Did they mean to forget to include opts? Or was it intentional? The type of magic where we say one parameter can be treated in different ways is surprising, and not in a good way.
There was a problem hiding this comment.
I personally don't like this pattern, but I do see this used in lots of places :(
I guess the best way to escape is the make it an async function that returns a promise, so up to the caller whether to chain it or not
There was a problem hiding this comment.
@weizou19 pointed out to me that Node itself does this (magic overloading of provided callbacks) (https://github.com/nodejs/node/blob/master/lib/fs.js#L405-L414) so as much as I dislike it I'm going to say I'm wrong on this.
|
|
||
| if (opts) { | ||
| if (typeof opts === 'string') { | ||
| if (typeof opts === 'function') { |
There was a problem hiding this comment.
Didn't answer my question, but I really dislike this - let's keep each parameter as it's meant to be instead of pseudo-overloading.
| callback = opts; | ||
| opts = {}; | ||
| } | ||
| if (!opts) opts = {}; |
There was a problem hiding this comment.
I prefer opts = opts || {}; format. If you do have it this way, let's bracket the clause in the if - 1 line if statements like this can lead to errors when refactoring.
| let sentLevels = []; | ||
|
|
||
| let callbackResult; | ||
| const testCallback = (er, res) => { callbackResult = res;}; |
There was a problem hiding this comment.
Correct me if I'm wrong, but it appears the only place the callback is actually called (and not just passed along) is in Logger._flush(), and that seems to call callback without any params, so how does this work?
There was a problem hiding this comment.
@dchai76 it attaches the callback to the instance line 340 and in the async function send_request it calls the callback that was passed specifically for that instance.
|
|
||
| if (opts) { | ||
| if (typeof opts === 'string') { | ||
| if (typeof opts === 'function') { |
There was a problem hiding this comment.
@weizou19 pointed out to me that Node itself does this (magic overloading of provided callbacks) (https://github.com/nodejs/node/blob/master/lib/fs.js#L405-L414) so as much as I dislike it I'm going to say I'm wrong on this.
| configs.LOG_LEVELS.forEach(function(level) { | ||
| var l = level.toLowerCase(); | ||
| Logger.prototype[l] = function(statement, opts) { | ||
| var levelFuncationName = level.toLowerCase(); |
There was a problem hiding this comment.
Make this a const and fix the spelling
There was a problem hiding this comment.
We should set "no-var": "error" to enforce it: https://github.com/logdna/nodejs/blob/master/.eslintrc#L219
| done(); | ||
| }, configs.FLUSH_INTERVAL + 200); | ||
| }); | ||
| it('Debug Functio, when called with callback, should call the cb', function(done) { |
There was a problem hiding this comment.
While it's up to you, I would add a nested describe for these (describe('Debug Function'...) so that the actual test names only say the expected behavior (it('Executes callback when provided'...)`)
| } | ||
|
|
||
| if (!callback || typeof callback !== 'function') { | ||
| callback = (err) => {debug(err);}; |
There was a problem hiding this comment.
Would prefer spaces between the brackets
There was a problem hiding this comment.
Another linting rule to add
https://github.com/logdna/nodejs/blob/master/.eslintrc#L226
"space-in-brackets": "always"
| let sentLevels = []; | ||
|
|
||
| let callbackResult; | ||
| const testCallback = (er, res) => { callbackResult = res;}; |
There was a problem hiding this comment.
Would prefer a space before the closing bracket
Adds an option to pass a callback when the log (or any other logging function) is called. It will pass the object with the response code and the response or an error to the callback after sending the request to the server.