AWS Lamda / API Gateway Каждый второй вызов приводит к внутренней ошибке сервера - PullRequest
0 голосов
/ 11 мая 2018

Мне нужно «Nodejs» и «Serveless».Я создал API без сервера и развернул его в AWS.Все работает как положено.Проблема, которая у меня есть, и я не могу найти ничего об этом, при каждом втором вызове я получаю внутреннюю ошибку сервера.первый вызов возвращает данные, как и ожидалось.

Я развернул в AWS только на этапе разработки.Мне интересно, есть ли какая-то конфигурация, которую я пропускаю или что-то еще?

Если вам нужна конфигурация 'Serverless' или примеры кода, которые я могу предоставить.

Спасибо.

ОТВЕТ

Я думаю, что была проблема с вызовом DB, не возвращающим данные вовремя для обратного вызова, поэтому я нашел противоречивые результаты.

Так что в основном то, что яЯ создал класс базы данных, возвращающий обещания следующим образом ...

'use strict';

const mysql = require('mysql');

/**
 * Database
 */
class Database {

    constructor(config) {
        if (!this.dbConnection) {

            console.log('connect to DB');

            this.dbConnection = mysql.createPool(config);

            this.dbConnection.on('connection', (connection) => {
                console.info('Connection Made!');
            });
        }
    }

    query(sql, args) {

        return new Promise((resolve, reject) => {

            this.dbConnection.query(sql, args, (err, rows) => {
                if (err) {
                    reject(err);
                }

                resolve(rows);
            })
        });
    }

    close() {
        return new Promise((resolve, reject) => {

            this.dbConnection.end((error) => {

                if (error) {
                    reject(error);
                }

                resolve();
            });
        });
    }
}

module.exports = Database;

Поэтому, когда я сделал свой запрос, был результат, готовый к обратному вызову.

'use strict';

const Database = require('./lib/Database');
const {successResponse, errorResponse} = require('./lib/response');
const CategoryResource = require('./resource/Category');

module.exports.list = (event, context, callback) => {

    let sql = 'SELECT * FROM categories AS c WHERE c.company_id = ? AND c.parent_id IS NULL AND c.status = 1 LIMIT ?, ?;';
    const company = parseInt(event.queryStringParameters.company);

    let page = 1;
    let limit = 20;

    if (null != event.queryStringParameters) {
        if ('page' in event.queryStringParameters) {
            page = parseInt(event.queryStringParameters.page);
        }

        if ('limit' in event.queryStringParameters) {
            limit = parseInt(event.queryStringParameters.limit);
        }
    }

    let start = (page - 1) * limit;

    if (isNaN(company)) {
        callback(null, errorResponse(400, 'Company ID Required', 'Parameter company_id is required.', []));
        return;
    }

    let Category = new Database();
    let categoryResource = [];

    Category
        .query(sql, [company, start, limit])
        .then(response => {

            Category.close();

            response.forEach((category) => {
                categoryResource.push(CategoryResource(category));
            });

            callback(null, successResponse(200, {
                "total": response.length,
                "perPage": limit,
                "currentPage": page,
                "data": categoryResource
            }));

        })
        .catch((error) => {

            callback(null, errorResponse(error.code, error.sqlMessage, error.sql, {
                code: error.errno,
                field: error.sqlMessage,
                message: error.sqlMessage
            }));

            Category.close();
        });
};

Надеюсь, это поможетлюбой, кто мог столкнуться с той же проблемой.

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Я думаю, что была проблема с вызовом DB, который не возвращал данные вовремя для обратного вызова, поэтому я нашел противоречивые результаты.

Итак, в основном я создал класс Database, возвращающий Promises, вот так...

'use strict';

const mysql = require('mysql');

/**
 * Database
 */
class Database {

    constructor(config) {
        if (!this.dbConnection) {

            console.log('connect to DB');

            this.dbConnection = mysql.createPool(config);

            this.dbConnection.on('connection', (connection) => {
                console.info('Connection Made!');
            });
        }
    }

    query(sql, args) {

        return new Promise((resolve, reject) => {

            this.dbConnection.query(sql, args, (err, rows) => {
                if (err) {
                    reject(err);
                }

                resolve(rows);
            })
        });
    }

    close() {
        return new Promise((resolve, reject) => {

            this.dbConnection.end((error) => {

                if (error) {
                    reject(error);
                }

                resolve();
            });
        });
    }
}

module.exports = Database;

Поэтому, когда я сделал свой запрос, был результат, готовый к обратному вызову.

'use strict';

const Database = require('./lib/Database');
const {successResponse, errorResponse} = require('./lib/response');
const CategoryResource = require('./resource/Category');

module.exports.list = (event, context, callback) => {

    let sql = 'SELECT * FROM categories AS c WHERE c.company_id = ? AND c.parent_id IS NULL AND c.status = 1 LIMIT ?, ?;';
    const company = parseInt(event.queryStringParameters.company);

    let page = 1;
    let limit = 20;

    if (null != event.queryStringParameters) {
        if ('page' in event.queryStringParameters) {
            page = parseInt(event.queryStringParameters.page);
        }

        if ('limit' in event.queryStringParameters) {
            limit = parseInt(event.queryStringParameters.limit);
        }
    }

    let start = (page - 1) * limit;

    if (isNaN(company)) {
        callback(null, errorResponse(400, 'Company ID Required', 'Parameter company_id is required.', []));
        return;
    }

    let Category = new Database();
    let categoryResource = [];

    Category
        .query(sql, [company, start, limit])
        .then(response => {

            Category.close();

            response.forEach((category) => {
                categoryResource.push(CategoryResource(category));
            });

            callback(null, successResponse(200, {
                "total": response.length,
                "perPage": limit,
                "currentPage": page,
                "data": categoryResource
            }));

        })
        .catch((error) => {

            callback(null, errorResponse(error.code, error.sqlMessage, error.sql, {
                code: error.errno,
                field: error.sqlMessage,
                message: error.sqlMessage
            }));

            Category.close();
        });
};

Я надеюсь, что это поможет любому, кто может столкнуться с той же проблемой.

0 голосов
/ 11 мая 2018

Если каждый раз, когда вы получаете внутреннюю ошибку сервера, это означает, что ваш код синтаксически исправен, но имеет какую-то логическую ошибку.Без примера кода невозможно обойтись, но некоторые из наиболее распространенных ошибок, которые я видел, которые встречаются только иногда, могут быть:

  • условия гонки (если вы делаете параллельный доступ к одному и тому же массиву,например)
  • ошибки доступа к массиву (длина + 1 вместо длины-1, меньше нуля, или ваши итераторы прыгают где-то в памяти, что они не должны)
  • просто упоминаянеправильная переменная (например, вместо ij вместо i)

К сожалению, без конкретных примеров лучшее, что мы можем предложить, - это дикие спекуляции и личный опыт.Вы пытались посмотреть на AWS CloudWatch и что он говорит о вашем исполнении?Там тоже должно быть несколько ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...