Node.js Sequelize getter / setter RangeError

I am creating a table to store user sessions. I will store the IP address as an integer using the following methods: Do the IP addresses stored as int lead to overflow?

I would like to specify getter and setter for the IP field so that it can automatically convert between IP and int.

Unfortunately, I get the following error, and I have no idea what is going on. I have been trying to fix this for several hours and Google is not giving me any results:

RangeError: Maximum call stack size exceeded

Model:

 model = db.define(name, { id: {type: Sequelize.STRING, allowNull: false, primaryKey: true}, ipAddress: {type: Sequelize.INTEGER(11).UNSIGNED, allowNull: false}, userAgent: {type: Sequelize.STRING, allowNull: false}, username: {type: Sequelize.STRING, allowNull: false}, password: {type: Sequelize.STRING, allowNull: false}, firstName: {type: Sequelize.STRING, allowNull: false}, lastName: {type: Sequelize.STRING, allowNull: false}, email: {type: Sequelize.STRING} }, { getterMethods: { name: function() { return this.firstName + this.lastName }, ipAddress: function() { ip = this.getDataValue("ipAddress"); return ((ip >> 24) & 255) + "." + ((ip >> 16) & 255) + "." + ((ip >> 8) & 255) + "." + (ip & 255); } }, setterMethods: { ipAddress: function(ip) { var parts = ip.split("."); var ret = 0; ret += parseInt(parts[0], 10) << 24; ret += parseInt(parts[1], 10) << 16; ret += parseInt(parts[2], 10) << 8; ret += parseInt(parts[3], 10); return ret; } } }); 

IP insert:

 model.findOrCreate({id: sessionId}, { id: sessionId, ipAddress: req.ip, // === "192.168.1.79" userAgent: req.get("user-agent"), username: "test", password: "test", firstName: "first", lastName: "last", email: "email" }) 

I can confirm that the getter / setter code is converted as desired, but it does not work correctly in Sequelize.

+4
source share
3 answers

I also ran into this issue with Sequelize. I read and re-read the official documentation, searched everywhere I knew to search the Internet, and I finally ended up here. As soon as I found your question, without answers, I decided to find the source code of Sequelize. Of course I found the answer!

If you look at the sequelize/test/dao-factory.test.js file in the sequelize/test/dao-factory.test.js source code, you will find the following bit of code hiding inside the test case:

 setterMethods: { price1: function(v) { this.setDataValue('price1', v * 100) } }, 

I copied the syntax above, used it in my setter method, and it works!

They really need to update the documentation on the sequelize website .. Hmm .. Maybe I should help them with this? In any case, you are more fortunate!

+4
source

I don’t know, someone is still running this error, but if you have any problems with this, here is how I solved the problem.

I had a similar situation when I had a UserModel object that looked like this:

 var UserModel = sequelize.define("users", { ID: { type: Sequelize.INTEGER, field: "ID", primaryKey: true, autoIncrement: true }, Username: { type: Sequelize.STRING, field: "Username" }, Password: { type: Sequelize.STRING, field: "Password" }, Sector: { type: Sequelize.INTEGER, field: "Sector" }, SubSector: { type: Sequelize.INTEGER, field: "SubSector" }, Email: { type: Sequelize.STRING, field: "email" }, Status: { type: Sequelize.INTEGER, field: "status" } } 

And my setters and getters:

 { getterMethods: { Sector: function() { return this.Sector; }, Status: function() { return this.Status; } }, setterMethods: { Sector: function(val) { this.setDataValue('Sector',val); }, Status: function(val) { this.setDataValue('Status',val); } } }); 

And of course, I had a stack error.

To solve this problem, I just changed the settings and recipients:

  { getterMethods: { currSector: function() { return this.Sector; }, currStatus: function() { return this.Status; } }, setterMethods: { newSector: function(val) { this.setDataValue('Sector',val); }, newStatus: function(val) { this.setDataValue('Status',val); } } }); 

And everything went magically, despite the fact that in many examples online I saw people offering the approach of providing the same setter / getter name as the fields.

So, in a nutshell, changing the name of the setters and getters so that their name does not match any of the specific fields that solved my problem. Good practice? I'm not sure, but he solved my problem.

+1
source

I had a similar situation, and I decided in this way

 const ProductImages = db.define('product_images', { product_image_id: {type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true}, url: Sequelize.TEXT, product_id: Sequelize.INTEGER, is_primary: Sequelize.INTEGER, }, { timestamps: false, getterMethods: { is_primary() { return parseInt(this.dataValues.is_primary) }, }, scopes: { byDefault() { return { include: [{ model: ProductDescriptions, as: 'product_description', where: {language_id: 1} }] }; }, } }) module.exports = ProductImages; 

When I call this.davaValues.column_name, it does not call recoursive getterMethod for this column

+1
source

Source: https://habr.com/ru/post/1495240/


All Articles