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.
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));
}