Search code examples
javascriptconsole.lognewrelic

Console.log(responseObject) outputs hidden data that can't be referenced via the object which is what I am desperatly trying to do


I am trying to detect when an SSL handshake to a website fails. Right now, I have a response object that looks like this:

let r = request({url:"url", method: "HEAD", ...}, (res) => { console.log(res) })

This outputs the following log:

{ Error: write EPROTO 139898579974016:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/s3_pkt.c:1494:SSL alert number 40
139898579974016:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:../deps/openssl/openssl/ssl/s3_pkt.c:659:
at exports._errnoException (util.js:1020:11)
at WriteWrap.afterWrite (net.js:800:14) code: 'EPROTO', errno: 'EPROTO', syscall: 'write' }

Looks simple right? Just retrieve the message from the response object. However, when I look for the keys in the response object, the message is nowhere to be found.

console.log(Object.keys(res)) // [ 'code', 'errno', 'syscall' ]
r.on("error") {console.log(error)} // {code: 'EPROTO', errno: 'EPROTO', syscall: 'write' }

So how do I retrieve the rest of the contents that was logged?

I am querying the website using New Relic Synthetics which runs an instance of Selenium Webdriver 3.50 (using Node 6.11.2) against the website. I don't think that should make a difference since it is console.log() that we are talking about. It does limit my options though to only nodejs modules approved by New Relic but if there is anything non-standard that would help, I will figure a way to test it out.


Solution

  • The main information in an Error object is on its message property.

    If there are other properties, they may not be enumerable, and/or they may be inherited. Object.keys doesn't show you either non-enumerable or inherited properties.

    To see non-enumerable properties (and enumerable ones, but not ones named by Symbols), you can use Object.getOwnPropertyNames. To see Symbol-named properties (you probably don't need these), you can use Object.getOwnPropertySymbols. If you need to see inherited ones, you can use that in a loop where you use Object.getPrototypeOf to walk up the prototype chain.

    // Assuming `res` is the starting point, and assuming you don't want properties
    // from `Object.prototype` (if it's in the prototype chain)
    let allPropertyNames = [];
    for (let obj = res; obj && obj !== Object.prototype; obj = Object.getPrototypeOf(obj)) {
        allPropertyNames.push(...Object.getOwnPropertyNames(obj));
    }