// Cause an error and then log it. try { var foo = bar; } catch ( error ) { // NOTE: Unlike the core Error properties, this one will be iterable. error.customProperty = "Injected custom property."; logError( { message: "Something went wrong when trying to set Foo!" }, error ); } // ----------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------- // // Create a log-entry and log it to the console (for demo). function logError( entry, error ) { // Create a log-entry with the error data as a key off the entry. var data = extend( { _id: ( process.pid + "-" + Date.now() ), _timestamp: ( new Date() ).toUTCString(), }, entry, { error: extend( {}, error ) } ); // None of the native error objects properties are iterable. As such, we have to // explicitly check for error-specific properties that we want to track for future // debugging purposes. // -- // NOTE: If the Error object is a custom error object, it might have other // properties, but those will be handled implicitly by the extend() call above. [ "name", "message", "stack" ].forEach( function iterator( key ) { if ( error[ key ] && ! data.error[ key ] ) { data.error[ key ] = error[ key ]; } } ); // For demo, log to console. console.error( data ); } // I collapse the given argument list down into the destination object and return it. function extend( destination, source ) { for ( var i = 1, length = arguments.length ; i < length ; i++ ) { var source = arguments[ i ]; for ( var key in source ) { if ( source.hasOwnProperty( key ) ) { destination[ key ] = source[ key ]; } } } return( destination ); }