Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

logger crashes on moment.js object ( TypeError: config._d.getTime is not a function ) #907

Closed
carchrae opened this issue Jun 25, 2021 · 9 comments · Fixed by #916
Closed

Comments

@carchrae
Copy link

carchrae commented Jun 25, 2021

Related issues

arguably, this is a bug with moment.js - but i'm not certain who should fix :
moment/moment#5011

[REQUIRED] Version info

node: 12 and 14

firebase-functions: 3.14.1

firebase-tools: 9.14.0

firebase-admin: 9.9.0

moment: 2.29.1

[REQUIRED] Test case

const functions = require('firebase-functions').logger;
const moment = require('moment');

console.log('this works', { m : moment() } );
console.log('this works too!', JSON.stringify({ m: moment() } ));

logger.info('wat!  this blows up!', { m : moment() } );
logger.info('but this works!', moment());

[REQUIRED] Steps to reproduce

simply run the test case

[REQUIRED] Expected behavior

logger should allow logging of moment object.

[REQUIRED] Actual behavior

note: this happens locally as well as when deployed

image

TypeError: config._d.getTime is not a function
    at new Moment (/workspace/node_modules/moment/moment.js:258:58)
    at Object.clone (/workspace/node_modules/moment/moment.js:3756:16)
    at Object.toISOString (/workspace/node_modules/moment/moment.js:3916:28)
    at Object.toJSON (/workspace/node_modules/moment/moment.js:4247:38)
    at JSON.stringify (<anonymous>)
    at write (/workspace/node_modules/firebase-functions/lib/logger.js:39:84)
    at Object.info (/workspace/node_modules/firebase-functions/lib/logger.js:81:5) 

Were you able to successfully deploy your functions?

yes

@google-oss-bot
Copy link
Collaborator

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

@carchrae
Copy link
Author

fwiw, i suspect the problem is with removeCircular somehow destroying the moment object:

function removeCircular(obj: any, refs: any[] = []): any {

@carchrae carchrae changed the title logger crashes with moment.js logger crashes on moment.js object ( TypeError: config._d.getTime is not a function ) Jun 25, 2021
@carchrae
Copy link
Author

btw a workaround is to simply never try to log a moment object. eg, always call moment.format() or moment.toDate()

@i14h
Copy link
Member

i14h commented Jun 28, 2021

thanks @carchrae for reporting this. @joehan can you please take a look into this?

@joehan
Copy link
Contributor

joehan commented Jun 28, 2021

Digging into this a bit, I think I see the issue. In removeCircular, we loop through all properties of the object and overwrite ones containing circular references with the string '[circular]'. For moment(), this ends up overwriting_d. JSON.stringify() calls moment().toJSON, which (after chaining through a few other functions), eventually tries to call _d.getTime. Since this has been overwritteb, this breaks

Gonna write up a quick fix to make this not break horribly, but in general this code is not well suited for complex objects that contain functions. To anyone else running into this issue or similar ones, I think @carchrae's solution of always calling moment.format() or moment.toDate() is still a good practice.

@carchrae
Copy link
Author

i appreciate not wanting to mess things up for currently deployed applications that rely on removeCircular. would be be a horrid idea to allow removeCircular to be disabled or customised? imho people logging objects with circular references are asking for trouble in the first place ;) - tho i appreciate util.inspect used to do something similar and i guess this is what you're trying to maintain.

the sad part for me, in terms of dev experience, is this blew a bunch of time. the other logging tools i used had no problem with moment - but i suspect they don't even try to handle circular refs.

one fix, with some performance cost is to wrap all calls to logger with something that transforms the object with JSON.parse(JSON.stringify(o)) - maybe that could that be used as a fallback too, or in some 'slow-but-more-robust' logger mode?

fwiw, there should absolutely be more care taken when logging in production (so many wasted cycles go there), but when debugging something i was just trying to dump state and got the strange error.

@mdinos
Copy link

mdinos commented Jun 30, 2021

Perhaps tangentially related, the logger doesn't seem to handle plain old Date objects either:
Screenshot 2021-06-30 at 15 47 27

@carchrae's suggestion of JSON.parse(JSON.stringify(o)) seems to do the trick as a workaround:
Screenshot 2021-06-30 at 15 53 39

@fahu
Copy link

fahu commented Jul 4, 2021

This bug seems to be introduced with v3.14. I used to log moment objects in version 3.13 and all worked fine. With version 3.14.1 it produces the above mentioned issue.

@joehan
Copy link
Contributor

joehan commented Jul 14, 2021

Hey all, I think this should be fixed after the PR is merged + released. This will go out in 3.15.0 - if you still face this issue after that point, please let me know!

@joehan joehan closed this as completed Jul 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants