Node.js + mongoose [RangeError: превышен максимальный размер стека вызовов]

Я новичок в Node.js и столкнулся с ошибкой:

RangeError: превышен максимальный размер стека вызовов

Я не могу решить проблему, потому что большинство проблем со стеком в других вопросах stackoverflow о Node.js связано с сотнями обратных вызовов, но у меня здесь только 3.

Сначала выборка (findById), затем обновление, а затем операция сохранения!

Мой код:

app.post('/poker/tables/:id/join', function(req, res) {
    var id = req.params.id;

    models.Table.findById(id, function(err, table) {
        if (err) {
            console.log(err);
            res.send({
                message: 'error'
            });
            return;
        }

        if (table.players.length >= table.maxPlayers) {
            res.send({
                message: "error: Can't join ! the Table is full"
            });
            return;
        }
        console.log('Table isnt Full');

        var BuyIn = table.minBuyIn;
        if (req.user.money < table.maxPlayers) {
            res.send({
                message: "error: Can't join ! Tou have not enough money"
            });
            return;
        }
        console.log('User has enought money');

        models.User.update({
            _id: req.user._id
        }, {
            $inc: {
                money: -BuyIn
            }
        }, function(err, numAffected) {
            if (err) {
                console.log(err);
                res.send({
                    message: 'error: Cant update your account'
                });
                return;
            }
            console.log('User money updated');

            table.players.push({
                userId: req.user._id,
                username: req.user.username,
                chips: BuyIn,
                cards: {}
            });

            table.save(function(err) {
                if (err) {
                    console.log(err);
                    res.send({
                        message: 'error'
                    });
                    return;
                }

                console.log('Table Successfully saved with new player!');
                res.send({
                    message: 'success',
                    table: table
                });

            });
        });

    });
});

Ошибка возникает при сохранении в конце!

Я использую MongoDb с mongoose, поэтому Table и User - мои коллекции баз данных.

Это из моего первого проекта с Node.js, Express.js и MongoDB, поэтому я, вероятно, сделал огромные ошибки в асинхронном коде :(

РЕДАКТИРОВАТЬ: я попытался заменить сохранение обновлением:

models.Table.update({
    _id: table._id
}, {
    '$push': {
        players: {
            userId: req.user._id,
            username: req.user.username,
            chips: BuyIn,
            cards: {}
        }
    }
}, function(err, numAffected) {

    if (err) {
        console.log(err);
        res.send({
            message: 'error'
        });
        return;
    }

    console.log('Table Successfully saved with new player!');
    res.send({
        message: 'success',
        table: table
    });

});

Но это не помогает, ошибка все еще возникает, и я не знаю, как ее отлаживать: /


person prdox    schedule 20.05.2012    source источник
comment
Пожалуйста, разместите свой ответ в разделе ответов.   -  person casperOne    schedule 17.08.2012
comment
Не то чтобы это вызвало проблему с размером стека, но эта строка определенно выглядит неправильно: if(req.user.money < table.maxPlayers). Нет ничего более плохого в том, что вы делаете.   -  person JohnnyHK    schedule 30.08.2012
comment
Вы получаете эту ошибку после нескольких запросов или после первого запроса?   -  person c0deNinja    schedule 30.08.2012


Ответы (4)


Я тоже сталкивался с этой проблемой. Обычно, когда у вас есть свойство с ref и вы хотите использовать его, например, при поиске, вы не можете передать весь документ.

Например:

Model.find().where( "property", OtherModelInstance );

это вызовет эту ошибку.

Однако на данный момент у вас есть 2 способа исправить это:

Model.find().where( "property", OtherModelInstance._id );
// or
Model.find().where( "property", OtherModelInstance.toObject() );

На данный момент это может решить ваши проблемы.

В их репозитории на GitHub есть проблема, о которой я сообщил, но пока она без исправлений. См. проблему здесь.

person gustavohenke    schedule 22.02.2013
comment
Юп, столкнулся с той же проблемой два месяца назад, исправил ее, но не записал, как ... Теперь я снова наткнулся на нее, что заставило меня искать этот пост и голосовать за него ;-) - person BenSower; 21.09.2016

Я продолжал получать эту ошибку и, наконец, понял ее. Это очень сложно отлаживать, поскольку в ошибке нет реальной информации.

Оказывается, я пытался сохранить объект в поле. Сохранение только определенного свойства объекта или его преобразование в JSON сработало как шарм.

Вроде бы неплохо, если бы драйвер выдавал более конкретную ошибку, ну да ладно.

person rgoldfinger    schedule 30.06.2014
comment
Предоставляя ответы на старые вопросы, это помогает объяснить, чем ваш ответ отличается от существующих. В этом случае ваш ответ выглядит как подмножество ответа, предоставленного gustavohenke. - person Jason Aller; 30.06.2014

MyModel.collection.insert причины:

[RangeError: превышен максимальный размер стека вызовов]

Когда вы передаете массив экземпляров MyModel вместо простого массива со значениями этих объектов.

RangeError:

let myArray = [];

myArray.push( new MyModel({ prop1: true, prop2: false }) );

MyModel.collection.insert(myArray, callback);

Нет ошибки:

let myArray = [];

myArray.push( { prop1: true, prop2: false } );

MyModel.collection.insert(myArray, callback);
person Daniel Kmak    schedule 08.10.2015

Есть несколько способов отладки приложений nodejs

Встроенный отладчик

Отладчик Node.js задокументирован здесь: http://nodejs.org/api/debugger.html

Чтобы разместить точки останова, просто поместите debugger; в то место, которое хотите разорвать. Как вы сказали, обратный вызов table.save вызывает проблемы, вы можете установить точку останова внутри этой функции.

Затем вы запускаете узел с включенным отладчиком:

node debug myscript.js

И вы получите более полезный результат.

Исследование стека

Вы также можете использовать console.trace для печати трассировки стека, если у вас есть хорошее представление о том, когда и где вы столкнулись с проблемами, и хотите выяснить, как вы к ним пришли.

Удачи, надеюсь, это поможет!

person Jared Forsyth    schedule 30.08.2012
comment
Спасибо за ваш ответ. Я не знал, что существует встроенный отладчик - я думал, что мне нужно установить инспектор узлов, если я хочу проверить свой код! - person Aaron; 01.03.2013
comment
Рад, что это сработало! пожалуйста, примите мой ответ как решение, если он вам понравился. - person Jared Forsyth; 02.03.2013