How to properly log error object in javascript - javascript

I am a fairly new to web development and have not given much thought to error. But today I noticed something I have to use json.stringyfy() to see the entire error object. Also message key is not shown in statement 2 but when I print error.message I get a message instead of undefined.
"message" is not even a key(check statement 4) but still logging error.message logs a value(typeof(error.message) is string) .
try {
//Some error occours
} catch (error) {
console.log(JSON.stringify(error)) //statement 1
console.error(error) //statement 2
console.log(error.message) //statement 3
console.log(Object.keys(error)) //statement 4
}
statement 1 logs
MongoServerError: E11000 duplicate key error collection: trendyApp.Markets index: name_1 dup key: { name: "murat market" }
at D:\web projects\trendyApp\server\node_modules\mongodb\lib\operations\insert.js:51:33
at D:\web projects\trendyApp\server\node_modules\mongodb\lib\cmap\connection_pool.js:273:25
at handleOperationResult (D:\web projects\trendyApp\server\node_modules\mongodb\lib\sdam\server.js:363:9)
at MessageStream.messageHandler (D:\web projects\trendyApp\server\node_modules\mongodb\lib\cmap\connection.js:474:9)
at MessageStream.emit (events.js:375:28)
at processIncomingData (D:\web projects\trendyApp\server\node_modules\mongodb\lib\cmap\message_stream.js:108:16)
at MessageStream._write (D:\web projects\trendyApp\server\node_modules\mongodb\lib\cmap\message_stream.js:28:9)
at writeOrBuffer (internal/streams/writable.js:358:12)
at MessageStream.Writable.write (internal/streams/writable.js:303:10)
at TLSSocket.ondata (internal/streams/readable.js:726:22) {
index: 0,
code: 11000,
keyPattern: { name: 1 },
keyValue: { name: 'murat market' }
}
statement 2 logs
{"index":0,"code":11000,"keyPattern":{"name":1},"keyValue":{"name":"murat market"}}
statement 3 logs
E11000 duplicate key error collection: trendyApp.Markets index: name_1 dup key: { name: "murat market" }
I saw this behavior while I was making an express application and the error is generated by mongoose but I think this would be common throughout javascript
statement 4 logs
[ 'index', 'code', 'keyPattern', 'keyValue' ]

"message" is not even a key(check statement 4)
It is, but Object.keys is designed to list enumerable properties, and message is not enumerable.
In the ECMAScript specification, we see in the section on the Error constructor that the constructor creates its message (and other properties) with the procedure:
Perform CreateNonEnumerableDataPropertyOrThrow(O, "message", msg).
Other -- custom -- properties can of course be added to Error objects by JavaScript code, which explains why other properties are listed by Object.keys().
As to the output of console.log: the console API implementation has a lot of freedom on how to display objects -- lot's of differences can be found between implementations.
To also output those non-enumerable properties, use
console.log(Object.getOwnPropertyNames(error))

As #trincot said, it is not shown because of message is a non enumerable attribute for Error constructor, the MongoServerError is overriding the MongoError and actually this is overriding the JS Error object, so if you need to know what attributes you have into the error you can check the previous links to see what attributes you can check.
Also if you want to get all the attributes (included the non enumerable ones) you can use Object.getOwnProperties(error) to see all the attributes that the given object has.
Also you can use Object.getOwnPropertyDescriptors(error) to know what is the descriptor for each attribute you've defined into the given object.

Sadly error stack and message fields are not enumerable, below is a utility function that extracts all properties from an error object, even custom fields you assign to errors:
const err = new Error('Something bad happened.');
err.metadata = { custom: { field: '1' } };
console.log(errorToPOJO(err)); // {"stack":"Error: Something bad happened.\\n at <anonymous>:1:13","message":"Something bad happened.","metadata":{"custom":{"field":"1"}}
function errorToPOJO(error) {
const ret = {};
for (const properyName of Object.getOwnPropertyNames(error)) {
ret[properyName] = error[properyName];
}
return ret;
};

Try this if your using api
console.log(error.message.toString())

Related

TypeError: Cannot read property 'coins' of null Discord.js error

const db = require('quick.db');
module.exports = {
name: 'bal',
description: "Check your coin balance.",
execute(message, args) {
let profile = db.get(`${message.author.id}`)
if (!profile.coins) return message.lineReply('You currently have 0 coins.')
message.lineReply(`You currently have ${profile.coins} coins.`);
}
}
This is the command file for the balance command for my discord.js bot.
That script outputs this in the console:
TypeError: Cannot read property 'coins' of null
Here's more info about the database: https://quickdb.js.org/
TypeError: Cannot read property 'some object' of null
You are accessing a property of an object that is null. For example, document.getElementById('stuff') returns null. So adding .examplevalue will cause the error.
Test if an object is valid before accessing its property. (The object in question is profile).
Your db.get() is returning null, as in no value. Make sure that A) your database is set up correctly, and B) that the syntax for accessing said database is also correct. Otherwise this error is bound to be thrown.

Ramda: access input object's properties inside R.ifElse() function call

I have this existing function:
const inferProcessingError = R.ifElse(
R.propEq('conversionJobStatus', 3),
R.always('Last Process failed with error; please contact DevOps'),
R.always(null)
);
which is called like this:
const msg = inferProcessingError(jobStruct || {});
with this jobStruct:
{"id":9,"mediaGroupId":1000000,"conversionJobStatus":3,
"errorDetails": {
"Cause": {
"errorMessage": "MediaConvert Job Failed with ERROR status: ERROR Video codec [indeo4] is not a supported input video codec",
},
"Error": "Error",
}
}
and I need to create an error message string which includes the data from the Cause.errorMessage element.
This would be dead simple with a native JavaScript function, but I'm learning Ramda and want to just modify the existing code to include in the error message.
An R.prop('Cause')['errorMessage'] could work except that I can't figure out how to reference the jobStruct that was passed in to the inferProcessingError statement.
I can see that the R.ifElse and subsequent Ramda functions are able to get that reference, but when I embed an R.prop('Cause') in the error message string, it resolves to a function and not the value of the Cause element because it seems to be waiting for the data structure.
So...how do I gain access to the jobStruct reference? (arguments is not defined here).
UPDATE:
I can get this to work by referencing the original jobStruct as in R.Prop('ErrorDetails', jobStruct)['Cause']['errorMessage'] but that seems rather kludgy to me...
BUT if the call to inferProcessingError is actually inside a map statement and references an element in a larger structure, then the map index is not available to reference the data structure for the R.prop.
Perhaps you could use the pipe and path methods to achieve this "the ramda way".
Begin by using ramda's path() function to extract the nested errorMessage value from the input jobStruct object. Next, enclose that in a pipe() that transforms the extracted message into a string formatted with a custom error prefix:
const incCount = R.ifElse(
R.propEq('conversionJobStatus', 3),
/* Evaluate this pipe if the error case is satisfied */
R.pipe(
/* Path to extract message from input object */
R.path(["errorDetails", "Cause", "errorMessage"]),
/* Prefix string to extracted error message */
R.concat('Custom error prefix:')),
R.always('')
);
incCount({"id":9,"mediaGroupId":1000000,"conversionJobStatus":3,
"errorDetails": {
"Cause": {
"errorMessage": "MediaConvert Job Failed with ERROR etc etc",
},
"Error": "Error",
}
});
Here's a working example - hope that helps!
Update
Thanks to #customcommander for the suggestion to use concat for the string prefix, as well as returning an empty string value for the second branch

How to fix Uncaught TypeError: Cannot assign to read only property 'data' of object '#<ImageData>'

I'm trying to add data to my heatmap.
I use this library in order to do that
https://github.com/pa7/heatmap.js + the plugin from this.
This is my import:
<ltng:require styles='/resource/leafletMarkerCluster/Leaflet.markercluster-1.4.1/dist/MarkerCluster.css,
/resource/leafletMarkerCluster/Leaflet.markercluster-1.4.1/dist/MarkerCluster.Default.css'
scripts='/resource/leaflet/leaflet.js,/resource/leafletMarkerCluster/Leaflet.markercluster-1.4.1/dist/leaflet.markercluster.js,
/resource/LeafletHeatmapLayer/heatmap.js-develop/build/heatmap.js,
/resource/LeafletHeatmapLayer/heatmap.js-develop/plugins/leaflet-heatmap/leaflet-heatmap.js'
afterScriptsLoaded="{!c.jsLoaded}" />
Accounts are already defined:
locationsAccounts[i]=helper.heatpoint(account.ShippingLatitude, account.ShippingLongitude,1);
heatpoint: function Person(latitude, longitude, counter) {
return {
lat: latitude,
lng: longitude,
count: counter
};
}
var testData = { max: accounts.length,
data: locationsAccounts };
heatmapLayer.setData(testData);
Heatmap belongs to L.control.layers is one of the overlay.
UPDATE i saw that when im debugging i have this problem in the addData and setData methods :
Exception: TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them at Function.invokeGetter
I assume you're debugger breaks at this location. It's a piece of code that intentionally breaks the "strict" mode rule in order to generate an error so that the call stack can be picked from the resulting error. If you can ignore this error type in the debugger settings, chromium debugger will stop annoying you with it. It will only happen if Dexie.debug === true (which is the default for sites served from localhost). The feature you get in your console log, is an async stack trace of unhandled rejections. You can explicitly turn it off by setting Dexie.debug = false.
The source code looks like:
export function getErrorWithStack() {
"use strict";
if (NEEDS_THROW_FOR_STACK) try {
// Doing something naughty in strict mode here to trigger a specific error
// that can be explicitely ignored in debugger's exception settings.
// If we'd just throw new Error() here, IE's debugger's exception settings
// will just consider it as "exception thrown by javascript code" which is
// something you wouldn't want it to ignore.
getErrorWithStack.arguments;
throw new Error(); // Fallback if above line don't throw.
} catch(e) {
return e;
}
return new Error();
}

nextProps keys mysteriously inaccessible though it has content

I'm in componentWillReceiveProps(nextProps) in a react-redux app
console.log("Debug NextProps: ",nextProps.variantCategories);
console.log("Debug NextProps: ",Object.keys(nextProps.variantCategories));
//nextProps.variantCategories[1] returns undefined <-- I need to access this
I got an empty array for Object.keys and so I thought I might be accessing things wrongly and tested the same on a brand new object i,
let i={1: {key: "value"}};
console.log("Debug i: ",i);
console.log("Debug i: ",Object.keys(i));
And here's the console (expanded on the right column)
What am I doing wrong?
What is most likely the case that you are seeing is that the property 1 is not enumerable, that is to say you are not allowed to access it in a traditional sense as a property.
The inspectors in most browsers nowadays reveal all aspects of a JavaScript Object in the console, but that doesn't mean your code will have the same permission or access to retrieve that data. To recreate the issue that appears to be happening, you can try this code snippet:
var specialObject = Object.defineProperty({}, '1', {
enumerable: false,
value: 'some stuff here'
});
// console logging in an inspector would show the full contents
console.log(specialObject);
// prints: > Object {1: "some stuff here"}
// but trying to access the property as an enumerated value will not work:
console.log(Object.keys(specialObject));
// prints: > []
So the question I have - where is that data coming from? Seems like you were expecting a more plain object.
I mutated the object before that the app started to react in such a strange and mysterious way!
And this can be found by checking console logs done before fetching data and those would retain values that are current values.

Bad value error in Oboe.js

Originally asked by Sashkan on the Oboe.js Github issues:
I'm getting a stremedResponse from a distant API. When I make an ajax call, I get the following response :
{"company_id":"3e1f975601f59090decc8f2d5ced72010162e481","airplane_type_id":"c10143316664f220a5cb87950b3dbac8794e2b15","legs":
[{"lfi_from":"FR49348","lfi_to":"FR24863","nb_pax":"1","datetime_from":"2015-12-10 15:45:00","datetime_to":"2015-12-10 16:44:00","duration":"00:59","availability":true}]},{"company_id":"3e1f975601f59090decc8f2d5ced72010162e481","airplane_type_id":"opfr8976xwqs54321zdickv678654xckvjfdf025","legs":
[{"lfi_from":"FR49348","lfi_to":"FR24863","nb_pax":"1","datetime_from":"2015-12-10 15:45:00","datetime_to":"2015-12-10 16:45:00","duration":"01:00","availability":true}]},{"company_id":"3e1f975601f59090decc8f2d5ced72010162e48e","airplane_type_id":"2368c24e9980e4eb9ccd986f32df884e5bd58707","legs":
[{"lfi_from":"FR49348","lfi_to":"FR24863","nb_pax":"1","datetime_from":"2015-12-10 15:45:00","datetime_to":"2015-12-10 16:50:00","duration":"01:05","availability":true}]}
But when I use oboe, only the first one is displayed, and immediately after, I get the following oboe error:
thrown: Error: Bad value Ln: 1 Col: 65 Chr: , at Error (native) at emitError (http://openjetfrontclean/app_dev.php/bundles/main_oboe-browser_9.js:636:20) at handleData (http://openjetfrontclean/app_dev.php/bundles/main_oboe-browser_9.js:816:20) at applyEach (http://openjetfrontclean/app_dev.php/bundles/main_oboe-browser_9.js:497:20) at emit (http://openjetfrontclean/app_dev.php/bundles/main_oboe-browser_9.js:2042:10) at XMLHttpRequest.handleProgress (http://openjetfrontclean/app_dev.php/bundles/main_oboe-browser_9.js:1253:10)
message: "Bad value↵Ln: 1↵Col: 65↵Chr: ,"
stack: (...)
get stack: ()
set stack: ()
__proto__: DefineError.bh
Any idea why ?
Answer provided by JuanCaicedo
I think that response is invalid json, which you can verify by plugging it in to http://jsonlint.com/. It looks like it's three comma-separated objects. I think it's meant to be an array? If so, just add a [ at the start of the first object and a ] at the end of the last object.
Oboe is able to pick items out of a top-level array. Call .node('[*]', function(){...}).

Categories