when copy node js custom error class super Error variable is gone - node.js

I have a custom Err class that extends from Error class. all thing was good until I copy an instance of Err class. the super's variables of copied instance are undefined!
here is my code:
class Err extends Error {
constructor(code, msg) {
super(msg);
this.code = code;
}
}
const error = new Err(404, 'error message');
console.log(error);
/* { Error: error message
at repl:1:15
at Script.runInThisContext (vm.js:122:20)
at REPLServer.defaultEval (repl.js:332:29)
at bound (domain.js:402:14)
at REPLServer.runBound [as eval] (domain.js:415:12)
at REPLServer.onLine (repl.js:642:10)
at REPLServer.emit (events.js:203:15)
at REPLServer.EventEmitter.emit (domain.js:448:20)
at REPLServer.Interface._onLine (readline.js:308:10)
at REPLServer.Interface._line (readline.js:656:8) code: 404 }
*/
const copy = { ...error };
console.log(copy);
// { code: 404 }
// where is error.stack and error.name?
SOLUTION:
Change copy method to this
const copy= { ...error };
copy.name = error.name;
copy.message = error.message;
copy.stack = error.stack;
tanks PA.
if any one has a better solution tell it to me.

with copy = { ...error };
(1) the {} object literal operator, creates a new Object, not a new Err object,
and
(2) the ... or spread properties operator, for object literals, just copies the provided object own enumerable properties onto your new object.
To clone any javascript class instance with a perfect copy of properties, methods, getters/setters, non-enumerable properties, etc, ina a generic code is almost impossible. You may create your own copy/clone code for your particular case, with a combination of Object.assign() / Object.getPrototype() and custom tuning for inherited properties and internal classes.

Related

Stripe Webhook constructEvent method is returning 400 error when pointed to ec2 instance

I have developed my application in windows OS and integrated Stripe webhook with the help of ngrok. Everything was smooth and I was able to receive the events from webhook. but once I moved it to ec2 instance on AWS Cloud, it is throwing me an error.
Error: (In Stripe Dashboard Webhook Attempts Section)
Webhook Error: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined
It is strange that have not changed any piece of code and it still works on windows.
Complete Error:
TypeError [ERR_INVALID_ARG_TYPE]: The "key" argument must be of type string or an instance of Buffer, TypedArray, DataView, or KeyObject
. Received undefined
at prepareSecretKey (internal/crypto/keys.js:322:11)
at new Hmac (internal/crypto/hash.js:111:9)
at Object.createHmac (crypto.js:147:10)
at Object._computeSignature (/home/psuser/middleware/node_modules/stripe/lib/Webhooks.js:65:8)
at Object.verifyHeader (/home/psuser/middleware/node_modules/stripe/lib/Webhooks.js:107:36)
at Object.constructEvent (/home/psuser/middleware/node_modules/stripe/lib/Webhooks.js:12:20)
at /home/psuser/middleware/routes/carts.js:210:29
at Layer.handle [as handle_request] (/home/psuser/middleware/node_modules/express/lib/router/layer.js:95:5)
at next (/home/psuser/middleware/node_modules/express/lib/router/route.js:137:13)
at /home/psuser/middleware/node_modules/body-parser/lib/read.js:130:5
at invokeCallback (/home/psuser/middleware/node_modules/raw-body/index.js:224:16)
at done (/home/psuser/middleware/node_modules/raw-body/index.js:213:7)
at IncomingMessage.onEnd (/home/psuser/middleware/node_modules/raw-body/index.js:273:7)
at IncomingMessage.emit (events.js:327:22)
at endReadableNT (_stream_readable.js:1327:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
code: 'ERR_INVALID_ARG_TYPE'
}
The "key" argument must be of type string or an instance of Buffer, TypedArray, DataView, or KeyObject. Received undefined
// End point Code
router.post('/webhook', async (request, response) => {
const sig = request.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(request.rawBody, sig, process.env.STRIPE_WEBHOOK_SECRET);
}
catch (err) {
console.log(err.message);
return response.status(400).send(`Webhook Error: ${err.message}`);
}
});
// In app.js
app.use(express.json({
// Because Stripe needs the raw body, we compute it but only when hitting the Stripe callback URL.
verify: function (req, res, buf) {
var url = req.originalUrl;
if (url.endsWith('/webhook')) {
req.rawBody = buf.toString()
}
}
}));
You can install micro (npm install micro) which has its buffer method
const { buffer } = require('micro')
in order to create the required type for the request:
const reqBuffer = await buffer(req)
then you can do:
event = stripe.webhooks.constructEvent(reqBuffer, sig, process.env.STRIPE_WEBHOOK_SECRET);
But I think your problem is simply an ENV variable missing in your EC2 server did you export STRIPE_WEBHOOKS_SECRET=secret in your server?

TypeError: Cannot read property 'EventEmitter' of undefined typescript nodejs

I have a typescript application running on node.
I am using 'EventEmitter' class to emit a change in variable value.
This is my piece of code,
import events from 'events';
public async updateStream(streamContext: string, state: boolean): Promise<string> {
const eventEmitter = new events.EventEmitter();
if (state === true) {
return StreamManagement.instance.activeStreams.get(streamContext).streamState = 'Paused';
} else {
const streamState = StreamManagement.instance.activeStreams.get(streamContext).streamState = 'Active';
eventEmitter.emit('resume');
return streamState;
}
}
public async waitForStreamActive(stream: Stream) {
const eventEmitter = new events.EventEmitter();
// tslint:disable-next-line:no-unused-expression
return new Promise(( resolve ) => {
eventEmitter.on('resume', resolve );
});
}
This piece of code builds fine. But when i run the code, as in execute the operation, I am getting the following error,
error: errorHandler - Apply - Hit Unhandled exception {"timestamp":"2019-04-29T12:33:49.209Z"}
error: errorHandler - Apply - Cannot read property 'EventEmitter' of undefined - TypeError: Cannot read property 'EventEmitter' of undefined
at StreamResource.updateStream (C:\Vertigo\core\reference_platform\dist\index.js:10695:51)
at StreamService.patchStream (C:\Vertigo\core\reference_platform\dist\index.js:22524:40)
at process._tickCallback (internal/process/next_tick.js:68:7) {"timestamp":"2019-04-29T12:33:49.215Z"}
What am I doing wrong?
I've set up minimal project to reproduce it and immediately ts compiler warns me about:
TS1192: Module '"events"' has no default export.
But this seems to work:
import * as EventEmitter from 'events'
new EventEmitter();

NodeJS - TypeError: Cannot read property 'name' of undefined

I am getting the following error from my code: If you could help me that would be amazing! I am using discord.js!
TypeError: Cannot read property 'name' of undefined at
files.forEach.file (/root/eternity-bot/eternity-bot/index.js:21:33) at
Array.forEach () at fs.readdir
(/root/eternity-bot/eternity-bot/index.js:18:9) at
FSReqWrap.oncomplete (fs.js:135:15)
fs.readdir("./commands/", (err, files) => {
if (err) return console.error(err);
files.forEach(file => {
if (!file.endsWith(".js")) return;
let props = require(`./commands/${file}`);
console.log(`Loading Command: ${props.help.name}.`);
bot.commands.set(props.help.name, props);
props.conf.aliases.forEach(alias => {
bot.aliases.set(alias, props.help.name);
})
});
});
TypeError: A TypeError is thrown when an operand or argument passed to a function is incompatible with the type expected by that operator or function.
The possible cause is your props is not loaded correctly and doesn't include any property help, thus accessing property name of unknown property help throws TypeError. Similar to following:
let obj = {
o1: {
a: 'abc'
}
};
obj.o1 // gives {a: 'abc'}, as o1 is property obj which is an object.
obj.o1.a // gives 'abc', as a is property of o1, which is property of obj.
obj.o2 // undefined, as there's no o2 property in obj.
obj.o2.a // TypeError as there's no o2 property of obj and thus accessing property a of undefined gives error.
What is happening is that the code is working perfectly fine, but there seems to be some problem with the exports of your javascript files in the commands folder. Most probably, the help property is not defined in your files.

Invalid use of type "undefined" as a Firestore argument

I am getting error when I execute my code. Below code used for creating collection in cloud Firestore, before this I didn’t created any collection in cloud Firestore. It is empty. In the console.log, I am getting correct json object.
createEntry(subjectId: string, questionnaire: string, callback: (err: any, response: any) => void) :void {
let testEntity: TestEntity = new TestEntity(subjectId, questionnaire);
console.log("testEntity.toJSON();----------->",testEntity.toJSON());
var docRef = this.dbManager.collection('testQuestion').doc(subjectId);
var setAlan = docRef.set(testEntity.toJSON());
}
Here TestEntity is json values as below. All the fields have values.
public toJSON(): testEntry {
let returnJSON = {
"entry_id": this.entry_id,
"subject_id": this.subject_id,
"entry_date": this.entry_date,
"questionnaire": this.questionnaire,
"entry_start_timestamp": this.entry_start_timestamp,
"entry_end_timestamp": this.entry_end_timestamp,
"entry_complete": this.entry_complete,
"responses": this.responses,
"last_answered_question" : this.last_answered_question,
"entry_status" : this.entry_status
}
return returnJSON;
}
dbManager is this.adminInstance:
export class DatabaseManager{
private static adminInstance:any;
static getAdminInstance(): any {
if(!this.adminInstance)
admin.initializeApp(functions.config().firebase);
this.adminInstance = admin;
return this.adminInstance.firestore();
}
}
I am getting below error. How to solve it?
Error: Invalid use of type "undefined" as a Firestore argument.
at Object.exports.customObjectError.val [as customObjectError] (/user_code/node_modules/firebase-admin/node_modules/#google-cloud/firestore/src/validate.js:164:14)
at Function.encodeValue (/user_code/node_modules/firebase-admin/node_modules/#google-cloud/firestore/src/document.js:813:20)
at Function.encodeFields (/user_code/node_modules/firebase-admin/node_modules/#google-cloud/firestore/src/document.js:683:36)
at Function.fromObject (/user_code/node_modules/firebase-admin/node_modules/#google-cloud/firestore/src/document.js:223:55)
at WriteBatch.set (/user_code/node_modules/firebase-admin/node_modules/#google-cloud/firestore/src/write-batch.js:301:39)
at DocumentReference.set (/user_code/node_modules/firebase-admin/node_modules/#google-cloud/firestore/src/reference.js:420:8)
at testEntryService.createEntry (/user_code/services/test-entry-service.js:19:30)
at /user_code/services/intentService.js:22:36
at Function.<anonymous> (/user_code/node_modules/actions-on-google/dist/service/dialogflow/dialogflow.js:146:23)
at next (native)
Since I am new to Firebase, I am unable to identify this error. What is the root cause of the issue?

How do I extend the Error class?

This is my code:
let errorBadRequest = new Error("Bad request");
res.statusCode = 400;
errorBadRequest.errors = err.details.reduce(function(prev, current) {
prev[current.path] = current.message;
return prev;
}, {});
throw errorBadRequest;
I wanted to extend error attribute in error instance, but tsc said joi-utils.ts(21,23): error TS2339: Property 'errors' does not exist on type 'Error'.
The structure of errors is {fieldname: fieldmsg}, it's according to my joi request schema to decide.
How do I solve the error from typescript compiler? I think I need to declare a interface and be designate the attribute.
Property 'errors' does not exist on type 'Error'.
Create a file called error-extension.d.ts and have the following:
interface Error {
errors: Error;
}
More : https://basarat.gitbooks.io/typescript/content/docs/types/lib.d.ts.html
I find when initialing the Error class, actually it hasn't errors in Error . It should make a interface and set errors to option.
This is my solution:
interface IJoiErrorException extends NodeJS.ErrnoException {
errors?: Object;
}
const errorBadRequest: IJoiErrorException = new Error("Bad request");

Resources