Circular JSON stringify error without relevant stack trace on Nest.js - javascript

The following error is killing my application in production:
/usr/src/app/node_modules/#nestjs/common/services/console-logger.service.js:137
? `${this.colorize('Object:', logLevel)}\n${JSON.stringify(message, (key, value) => typeof value === 'bigint' ? value.toString() : value, 2)}\n`
^
TypeError: Converting circular structure to JSON
--> starting at object with constructor 'ClientRequest'
| property 'socket' -> object with constructor 'Socket'
--- property '_httpMessage' closes the circle
at JSON.stringify (<anonymous>)
at ConsoleLogger.stringifyMessage (/usr/src/app/node_modules/#nestjs/common/services/console-logger.service.js:137:62)
at ConsoleLogger.formatMessage (/usr/src/app/node_modules/#nestjs/common/services/console-logger.service.js:130:29)
at /usr/src/app/node_modules/#nestjs/common/services/console-logger.service.js:122:43
at Array.forEach (<anonymous>)
at ConsoleLogger.printMessages (/usr/src/app/node_modules/#nestjs/common/services/console-logger.service.js:117:18)
at ConsoleLogger.error (/usr/src/app/node_modules/#nestjs/common/services/console-logger.service.js:44:14)
at Logger.error (/usr/src/app/node_modules/#nestjs/common/services/logger.service.js:34:75)
at Logger.descriptor.value (/usr/src/app/node_modules/#nestjs/common/services/logger.service.js:163:27)
at ExceptionsHandler.handleUnknownError (/usr/src/app/node_modules/#nestjs/core/exceptions/base-exception-filter.js:54:43)
I can't reproduce it on development and I don't know what is causing this error. Is there any way to make the stack trace include the source of this error?
I already ran it with DEBUG=*, but it doesn't give me a conclusive answer.
I think the error is happening close to these lines (based on logs), but I can't tell for sure:
this.logger.error(error.toString())
throw new InternalServerErrorException(error.toString())
It doesn't seems to be related, because error.toString() evaluates to [object Object] (useless, but not wrong).

Based on the properties, it looks like probably an AxiosError or some other HTTP client error was thrown directly without being converted into an HttpException that Nest would know how to handle and Nest then tried to log out the error. I would check your uses of HttpService (if you use it) or any other HTTP clients you use. If you still can't find anything, I'd suggest using a different logger than Nest's that can handle circular JSON. My preference is ogma, but I'm also the author of it. pino is another good choice

Related

Show the faulty data when an assertion fails

Often when an assertion fails I want to see what kind of data caused the issue. That's very easy with the browser's developer tools, since I can see the values on the stack. But it's harder for node.js.
Is there any simple way to show the stack trace as well as the faulty values when an assertion fails, in a short-living node.js script?
This is problem that almost every node developer faces, right? I'm surprised that there's no obvious solution then.
How do you handle this?
Example
Here is a minimal example to show the problem:
import {strict as assert} from 'assert';
function sameX(a, b){
return a.x==b.x;
}
const a={x:1}; a.self=a;
const b={x:2}; b.self=b;
Let's say I expect sameX(a,b) to return true. If it doesn't, then I wish to print an error message, show the stack trace and show the current value of those variables.
How can I do it nicely in node?
❌ Failed attempt: extra arguments to node's assert
assert(sameX(a,b), "Objects with unexpected x", a, b);
This of course only prints:
Objects with unexpected x
since node's assert only takes two parameters.
❌ Failed attempt: stringify the objects
assert(sameX(a,b), `Objects with unexpected x ${a} ${b}`);
This prints:
Objects with unexpected x [object Object] [object Object]
I wish to see the content of a and b though.
❌ Failed attempt: JSON.stringify the objects
Something similar to:
assert(sameX(a,b), `Objects with unexpected x ${JSON.stringify(a)} ${JSON.stringify(b)}`);
Not only is a pain to type, but it may fail in some cases (like in this example where a and b have circular references).
❌ Failed attempt: console.assert
console.assert(sameX(a,b), "Objects with unexpected x", a, b);
This prints an error message I like:
Objects with unexpected x <ref *1> { x: 1, self: [Circular *1] } <ref *1> { x: 2, self: [Circular *1] }
However it doesn't throw an exception and thus doesn't even show the stack trace. I want to see the stack trace.
⚠️ Uncomfortable solution: connecting to the browser's developer tools
It's possible to debug Node using a browser's developer tools.
This works, but it's not a good option for a short-living/one-shot script that terminates in milliseconds.
Now, if there was something like a terminal that embeds the developer tools and connects them to the Node instance when one is in execution, that would be perfect. But I don't know any such terminal.
⚠️ Uncomfortable solution: custom assert function
Of course I can define my own assert function:
function assert(cond, ...msg){
if(!cond){
console.error("Assertion Failed!", ...msg);
throw new Error(msg[0]);
}
}
But I would have to copy and paste it in every project of mine and it would lack all the features of node's assert (for instance I would need to implement assert.deepEqual separately, if I need it).
A better alternative could be using an existing library. What library should I use for this though? After some searching I couldn't find any widespread library for this use case. Most assertion libraries are meant for test suites and are too heavy for production.

Disqus comments throws error in a Gatsby site

I am using a gatsby plugin gatsby-plugin-disqus(latest version) to add comments in my gatsby site. It worked previously but now it throws error and comments do not load. Seems like there's circular reference but I don't know what is causing it.
Uncaught TypeError: Converting circular structure to JSON
--> starting at object with constructor 'HTMLDivElement'
| property '__reactInternalInstance$ijgm46blrc' -> object with constructor 'FiberNode'
--- property 'stateNode' closes the circle
at JSON.stringify (<anonymous>)
at b.Channel.h.sendMessage (embed.js:44)
at e.<anonymous> (embed.js:45)
at e.<anonymous> (embed.js:44)
at e.<anonymous> (embed.js:44)
at m (embed.js:44)
at e.trigger (embed.js:44)
at e.<anonymous> (embed.js:44)
at m (embed.js:44)
at b.Channel.trigger (embed.js:44)
at embed.js:44
My disqus config looks like:
const disqusConfig = {
identifier: "/my-post-title-slug/"
title: "my post title"
url: "https://somesite.com/blog/my-post-title-slug/"
}
And i render it like this:
import { Disqus } from 'gatsby-plugin-disqus';
// ....
<Disqus config={disqusConfig} />
I am not sure what is causing this problem. I tried to use previous versions of the plugin but i get the same result.
Please let me know what i am missing here. Thanks.
That is... odd. You usually see this type of issue when attempting to stringify an object containing circuluar references. Ex:
VM1374:32 Uncaught TypeError: Converting circular structure to JSON(…)
But the object you're passing in is simple, containing only string values. I'm wondering if this isn't being caused by Disqus at all, but instead is something else in the mix.
To verify it shouldn't be an issue, I mimicked the exact same set up with a local Gatsby site of my own (v4), using the v1.2.4 of the Disqus package. I see no errors.
That said... my proposed steps:
Confirm that it's not being caused by a different package.
Try padding the config object directly into the component. I don't know why it'd yield a different result, but it's worth a shot:
<Disqus
config={{
identifier: "/my-post-title-slug/",
title: "my post title",
url: "https://somesite.com/blog/my-post-title-slug/"
}}
/>
If it's too much of a hassle, think about trying a Disqus alternative. I built one of my own after hitting a tons of frustrations with Disqus, including performance and lack of SEO-friendliness. You're welcome to try it out:
https://jamcomments.com

Vue.js Error "Cannot find module './undefined'" from webpack when using src=require()

I am trying to load images from a local folder using the src="" from the img tag but I want to load them using the backend. The frontend already has the relative path which is "../assets/imgs/" the backend just has the name and extension ex) "1.png". Thing is that it does work but I'm getting error messages.
This is causing me an issue
<img width=100px height=100px :src="getIconPath(`${user.icon}`)"/>
here is the function that gets called
methods: {
getIconPath(iconName) {
return iconName ? require("../assets/imgs/" + iconName) : ''
}
Here are both the error messages I am getting on the console
[Vue warn]: Error in render: "Error: Cannot find module './undefined'"
found in
---> <Profile> at src/components/profile.vue
<Navbar> at src/components/navbar.vue
<Main> at src/main.vue
<Root> vue.runtime.esm.js:619
Error: "Cannot find module './undefined'"
webpackContextResolve .*$:13
webpackContext .*$:8
getIconPath profile.vue:74
render profile.vue:12
VueJS 43
<anonymous> main.js:31
js app.js:1415
__webpack_require__ app.js:785
fn app.js:151
1 app.js:1488
__webpack_require__ app.js:785
checkDeferredModules app.js:46
<anonymous> app.js:861
<anonymous>
I found very little resources to help out but many of them have said that required fixes their issues. So far I tried moving it to a different folder, moving the require as a function method, using absolute path, using v-attr, and binding it without require. Still I haven't had any luck getting rid of the error message. Here is another link of someone else having the same issue as me but I still couldn't figure out how they fixed it.
https://forum.vuejs.org/t/how-to-fix-the-console-log-error-when-using-require-method-to-bind-an-img-src/77979
I would very much appreciate the help!! I've been stuck for many hours on this and I can't seem to find a helpful solution. If this isn't a good way to go about loading images from the backend feel free to suggest any other alternative ways to do so. Thank You!
I'm going to take a guess here and say that user is populated with data asynchronously. I bet you have something like this in your initial data or store
{
user: {}
}
The issue here is that user.icon is undefined, at least for some period of time. Where you are needlessly converting that into a string with
getIconPath(`${user.icon}`)
will convert undefined into the string "undefined" (because JavaScript is fun like that), hence your error message. The simple solution is to not use a string template, ie
getIconPath(user.icon)
To avoid these sorts of problems, I would instead use a computed property to resolve image imports. This is more efficient than executing a method in your template which happens on every tick
computed: {
userWithIcon () {
return {
...this.user,
icon: this.user.icon && require(`../assets/imgs/${this.user.icon}`)
}
}
}
and in your template
<img width="100px" height="100px" :src="userWithIcon.icon">
I had a similar issue recently and I was able to solve it by making sure that my data was ready before rendering the view. using #Phil assumption that you have something like user: {} in your data, you can just wrap your whole HTML in <div v-if="user !== null"></div>. This makes sure that the user data is ready before even trying to render any image at all or use any data from the user object.
This should eliminate any error at all.

Zombie.js unable to access dataset property of DOM elements

I have a page which contains a rich-text editor. I used CKEditor for this. You pass it a div element and it loads the editor into that element.
Now I wanted to write integration tests for that page. I am using zombie.js with version 4.2.1 (old, I know, but I'm stuck with it) for that purpose. However, I get an error just trying to load the page. The problem apparently happens while trying to load editor into the div element. This is the relevant output:
[some other resources loading]
zombie GET http://localhost:10003/js/lib/ckeditor.js => 200 +0ms
zombie GET http://localhost:10003/js/pages/categories/init.js => 200 +0ms
zombie http://localhost:10003/js/lib/ckeditor.js:6623
e.dataset.ckeFiller = true;
^
TypeError: Cannot set property 'ckeFiller' of undefined
at au (http://localhost:10003/js/lib/ckeditor.js:6623:37)
at Module.<anonymous> (http://localhost:10003/js/lib/ckeditor.js:7326:24)
at n (http://localhost:10003/js/lib/ckeditor.js:57:22)
at http://localhost:10003/js/lib/ckeditor.js:100:20
at http://localhost:10003/js/lib/ckeditor.js:101:10
at t (http://localhost:10003/js/lib/ckeditor.js:47:258)
at http://localhost:10003/js/lib/ckeditor.js:48:7
at Script.runInContext (vm.js:133:20)
at Object.runInContext (vm.js:311:6)
at window._evaluate (/home/laura/Projekte/fricke/hybristools/node_modules/zombie/lib/document.js:253:75)
in http://localhost:10003/categories +68ms
Debug-Output hier:
undefined
{ http://localhost:10003/js/lib/ckeditor.js:6623
e.dataset.ckeFiller = true;
^
TypeError: Cannot set property 'ckeFiller' of undefined
at au (http://localhost:10003/js/lib/ckeditor.js:6623:37)
at Module.<anonymous> (http://localhost:10003/js/lib/ckeditor.js:7326:24)
at n (http://localhost:10003/js/lib/ckeditor.js:57:22)
at http://localhost:10003/js/lib/ckeditor.js:100:20
at http://localhost:10003/js/lib/ckeditor.js:101:10
at t (http://localhost:10003/js/lib/ckeditor.js:47:258)
at http://localhost:10003/js/lib/ckeditor.js:48:7
at Script.runInContext (vm.js:133:20)
at Object.runInContext (vm.js:311:6)
at window._evaluate (/home/laura/Projekte/fricke/hybristools/node_modules/zombie/lib/document.js:253:75)
in http://localhost:10003/categories
cause:
http://localhost:10003/js/lib/ckeditor.js:6623
e.dataset.ckeFiller = true;
^
TypeError: Cannot set property 'ckeFiller' of undefined
at au (http://localhost:10003/js/lib/ckeditor.js:6623:37)
at Module.<anonymous> (http://localhost:10003/js/lib/ckeditor.js:7326:24)
at n (http://localhost:10003/js/lib/ckeditor.js:57:22)
at http://localhost:10003/js/lib/ckeditor.js:100:20
at http://localhost:10003/js/lib/ckeditor.js:101:10
at t (http://localhost:10003/js/lib/ckeditor.js:47:258)
at http://localhost:10003/js/lib/ckeditor.js:48:7
at Script.runInContext (vm.js:133:20)
at Object.runInContext (vm.js:311:6)
at window._evaluate (/home/laura/Projekte/fricke/hybristools/node_modules/zombie/lib/document.js:253:75)
in http://localhost:10003/categories,
isOperational: true }
I know that the error is not related to CKEditor because I tried it with another rich-text editor, which gave me the exact same error (only the property name was different).
The error apparently happens while trying to set the value of the HTML property "data-cke-filler" of a br element. This is the element:
That element is inserted into the editor at the time of creation, it represents the content of the editor, which is empty at the beginning.
I tried to use zombies debugging capabilites, however, as the error occurs while the site loads I don't really get a chance to output anything useful. As far as I am aware, zombie.js should be able to handle loading this page.
So my question is:
What is causing this error and how can I fix it?
Let me know if you need more information.
Thanks.
Edit:
Here is the code where I load the page (it's written in CoffeeScript):
require 'should'
Browser = require '../../support/browser'
describe 'editor page', ->
browser = new Browser({debug: true})
before (done) ->
browser.debug()
browser.visitLoggedIn('/', {name: 'tester', password: 'secret'})
.then (done) ->
browser.visitPage '/editor' # this is what doesn't work
.then (done) ->
console.log 'page loaded'
.catch (error) ->
console.error error
it 'things should appear', ->
...
The visitLoggedIn method is a custom method that just creates necessary cookies for browsing the application as an authenticated user and visits the page using visitPage. visitPage uses zombies visit method. These work fine in all the other integration tests of this application.
Edit 2:
So I managed to "mock" CKEdtor using this answer. This isn't exactly what I wanted, but I decided to try to work with this for now. However, now I get the exact same error! This time the error is thrown inside my own code:
# These are two functions that are run shortly after inserting the editor into the page,
# so basically while the page is still loading.
getLanguageChoice: -> # This one is executed first
document.getElementById('language').value
getMandantChoice: -> # This one second
document.getElementById('shopClient').dataset.name # The error is thrown here
This is the exact error:
TypeError: Cannot read property 'name' of undefined
at Object.CategoriesView.getMandantChoice (http://localhost:10003/js/pages/categories/view.js:49:59)
at http://localhost:10003/js/pages/categories/app.js:22:97
at process._tickCallback (internal/process/next_tick.js:68:7)
This doesn't make any sense to me. Does this mean that zombie somehow can't access the values of data-* attributes? Maybe someone is knowledgeable about zombie and can provide further insight?
After further looking around with the new insights I gained, I found this ticket on the Github page of the project. It looks like the dataset property is not implemented in an underlying library in the used version. As I am not able to upgrade, it's just not possible to load the page like it is...
To work around this, I will refactor my code to not use the data-* property. This is luckily not tied to too much work in my case.

I do not know the meaning of the error that is being displayed in the console

I was trying to make a website on the meteor platform. Everything was going well but now I am encountering these errors which are mentioned below:
<strong>Error: {{#each}} currently only accepts arrays, cursors or falsey values.<br/>
Exception from Tracker recompute function:<br/>
TypeError: Cannot read property '0' of null<br/>
at builtins.js:237<br/>
at Object.Tracker.nonreactive (tracker.js:589)<br/>
at Object.eachView.stopHandle.ObserveSequence.observe.changedAt (builtins.js:229)<br/>
at observe_sequence.js:274<br/>
at Function._.each._.forEach (underscore.js:113)<br/>
at diffArray (observe_sequence.js:260)<br/>
at observe_sequence.js:108<br/>
at Object.Tracker.nonreactive (tracker.js:589)<br/>
at observe_sequence.js:82<br/>
at Tracker.Computation._compute (tracker.js:323)<br/></strong>
I do not know from where these errors are coming. can any one help me regarding this. Apologies for any mistake in posting the question.
99% chances that you are passing an object to an #each in your template.
If you cannot identify easily that object because you have multiple #each, you can try to log the passed objects. With the following helper :
UI.registerHelper( 'log', ( content ) => {
return console.log( content );
} );
(and keep it, it's usefull)
Just log your elements that way :
{{log target}}
{{#each target}}
...
One of your targets is going to be null, an object or whatever, but not an array.

Categories