Javascript-форум (https://javascript.ru/forum/)
-   Node.JS (https://javascript.ru/forum/node-js-io-js/)
-   -   Express error handler (перенаправить в логи) (https://javascript.ru/forum/node-js-io-js/55447-express-error-handler-perenapravit-v-logi.html)

Gozar 28.04.2015 09:46

Express error handler (перенаправить в логи)
 
Первое.
Как в express 4 сохранять ошибки в логфайл и запретить отдавать в браузер? Буду благодарен за пример.

По умолчанию express шлет описание ошибки в браузер, что недопустимо на продакшене.

И второе.
Есть router http://expressjs.com/4x/api.html#router
var app = express();
var router = app.Router([options]);;
router.get('/events', funct)


Чем это отличается от:
var app = express();
app.get('/events', funct)

?

Непонимаю разницу.

Erolast 28.04.2015 11:52

Цитата:

По умолчанию express шлет описание ошибки в браузер, что недопустимо на продакшене.
Не будет слать при process.env.NODE_ENV == "production" (либо можно вручную установить через app.set("env", mode))

Цитата:

Как в express 4 сохранять ошибки в логфайл
Установи в конец миддлвер с аргументами err, req, res, next (то есть, с четырмя)
app.use((err, req, res, next) => {
  //Этот миддлвер будет обрабатывать ошибки.
});


Цитата:

router
Роутер позволяет делать вложенный роутинг:
let app = express();

let adminRouter = express.Router();

adminRouter.get("/articles", (req, res) => {
    res.render("admin/articles");
});

adminRouter.get("/gallery", (req, res) => {
    res.render("admin/gallery");
});

app.use("/admin", adminRouter);

Erolast 28.04.2015 12:00

А для логирования есть morgan.

Gozar 28.04.2015 12:16

Цитата:

Сообщение от Erolast
Установи в конец

У меня приложение разбросано по множеству папок и в них есть app.get, app.post ...

В конец, это куда?

После каждого app.get() или нужно проследить порядок подключения через require и поставить именно в конец объявления всего приложения?

Gozar 28.04.2015 12:20

Цитата:

Сообщение от Erolast
Pоутер позволяет

то, есть можно тоже самое написать:

let app = express();

app.get("/adimn/articles", (req, res) => {
    res.render("admin/articles");
});

app.get("/admin/gallery", (req, res) => {
    res.render("admin/gallery");
});

?

На скорость это как-то влияет или просто для построения архитектурных решений?

Erolast 28.04.2015 13:47

Цитата:

нужно проследить порядок подключения через require и поставить именно в конец объявления всего приложения?
Порядок подключения через use. Чтобы до логгера через next() дошла любая ошибка из любого миддлевера.

Цитата:

то, есть можно тоже самое написать:
Да.

Цитата:

На скорость это как-то влияет?
Эм... каким образом? Вроде да, просто для удобства.

Gozar 28.04.2015 13:59

Цитата:

Сообщение от Erolast
Порядок подключения через use. Чтобы до логгера через next() дошла любая ошибка из любого миддлевера.

Есть три файл:

init.js
global.app = express();
require('get.js');
require('post.js');


get.js
app.get('/get/:id', funcHandlerPost);


post.js
app.post('/get/:id', funcHandlerPost);


Куда поставить?
app.use((err, req, res, next) => {
  //Этот миддлвер будет обрабатывать ошибки.
});

Erolast 28.04.2015 14:48

Чтобы подключился после всех остальных миддлеверов:
global.app = express();

require('get.js');
require('post.js')

app.use((err, req, res, next) => {
  //Этот миддлвер будет обрабатывать ошибки.
});

app.listen(3000);

Почему - потому что запрос идет по цепочке миддлверов как по потокам, и если поставить логгер в начале, до него попросту никогда ничего не дойдет.

Gozar 28.04.2015 15:33

Erolast,
Спасибо, теперь понял. :)

Erolast 29.04.2015 09:00

Только глобал ж в ноде не принято использовать. Почему не так:
let app = express();

app.use(require("./get"));
app.use(require("./post"));

app.listen(3000);

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

let morgan = require("morgan");
let app = express();

app.use(morgan());

app.listen(3000);

Gozar 29.04.2015 09:30

Цитата:

Сообщение от Erolast
глобал ж в ноде не принято использовать

:) Потихоньку выпиливаю, когда начинал 3 месяца назад, было не до тонкостей.

Если маленький проект подключаем так?

let app = express();

app.use(require("./get/info"));
app.use(require("./get/props"));

app.listen(3000);


Где:

./get/info

let app = express();

app.get('/get/info/', funcHandler);



А если большой?

let app = express();

app.use(require("./get/init"));

app.listen(3000);


Где:
./get/init

require('./info');
require('./props');
...

Где ./get/info
app.get('/get/info/', funcHandler);


Так?

Gozar 29.04.2015 11:06

А в ноде не без разницы let или var? Вроде же и так по модулям распихано.

kobezzza 29.04.2015 11:11

Цитата:

Сообщение от Gozar (Сообщение 368669)
А в ноде не без разницы let или var? Вроде же и так по модулям распихано.

var депрекейтед в ES6 :) А так без разницы.

Safort 29.04.2015 11:59

Цитата:

Сообщение от Gozar (Сообщение 368669)
А в ноде не без разницы let или var? Вроде же и так по модулям распихано.

Так Babel же)

Gozar 29.04.2015 12:19

Цитата:

Сообщение от Safort
Так Babel же)

Я не использую Babel на сервере. Хватает стандартного api+npm.

Erolast 29.04.2015 15:05

Цитата:

А в ноде не без разницы let или var? Вроде же и так по модулям распихано.
Во внешнем-то скопе разницы нету, но не объявлять же в разных стилях.

Цитата:

А если большой?
Я сейчас выделяю роутеры в отдельную папочку по сущностям (у меня, правда, ES6-модули, но не суть):
let app = express();

app.use("/", require("./routers/main"));
app.use("/api", require("./routers/api"));

app.listen(3000);

//routers/main.js
let express = require("express");
let router = express.Router();

router.use("/*", (req, res) => {
  res.render("main");
});

module.exports = router;

//routers/api.js
let express = require("express");
let httpStatuses = require("statuses");

let Article = require("../models/Article");

let router = express.Router();

router.route("/articles")
    .get((req, res, err) => {
        Article.find().then(
            (articles) => res.json(articles),
            (err) => next(err)
        );
    })
    .post((req, res, err) => {
        let article = new Article();
        
        article.save().then((article) => {
            res.status(httpStatuses.Created);
            res.location(req.protocol +
                "://" +
                req.hostname +
                (config.get("port") != 80 ? ":" + config.get("port") : "") +
                req.originalUrl +
                article.id
            );
            
            res.json(article);
        }, (err) => next(err));
    });

module.exports = router;


Когда роутер разрастается - он просто заменяется на папочку и разбивается на несколько мелких (именно поэтому я не указываю расширение при импорте).

Gozar 29.04.2015 17:58

Я немного по другому делю:
/get //-> читаем с сервера (в папке есть файл init в который подключаем файлы)
/set //-> пишем на сервер (в папке есть файл init в который подключаем файлы)

Т.к. я в основном использую тип JSON, то деление на get и post становиться немного неудобным, а то ещё присрется put ввести, хотя похоже мне он будет без надобности.

Мне было неясно зачем нужен let router = express.Router();. Теперь вижу, внутри ты делишь на get и post, если такого деление нет, то он без надобности и можно сразу писать app.get или app.post

Erolast 29.04.2015 19:37

Цитата:

Т.к. я в основном использую тип JSON, то деление на get и post становиться немного неудобным, а то ещё присрется put ввести, хотя похоже мне он будет без надобности.
Нихрена не понял. При чем тут JSON и в чем проблема ввести put?

Цитата:

внутри ты делишь на get и post
Это необязательно деление по методам, это может быть и деление по путям.

Gozar 29.04.2015 21:23

Цитата:

Сообщение от Erolast
Нихрена не понял

Я тебя ни в чем не убеждаю. Просто поделился архитектурным решением.

Ты написал роутер, внутри get, post. А я делю на get и set. Абстрагируюсь от типа(set: post, put, delete).

Цитата:

Сообщение от Erolast
чем проблема ввести put?

Да ни в чем. Просто он не нужен.

Erolast 30.04.2015 08:08

Цитата:

Я тебя ни в чем не убеждаю. Просто поделился архитектурным решением.
А. Ну я тоже ни в чем не убеждаю, просто поделился своим)

madgals 30.04.2015 23:41

тут у вас кто-то предлагал для записи логов ошибок использовать morgan, но это
Цитата:

HTTP request logger middleware for node.js
это как access log для апача или nginx. для лога ошибок можно использовать Winston.
Одним из способов, вероятно, можно вставить логгирование в тот же error handler callback экспресса, который первым аргументом принимает ошибку.

Gozar 01.05.2015 00:10

Цитата:

Сообщение от madgals
Одним из способов, вероятно, можно вставить логгирование в тот же error handler callback экспресса, который первым аргументом принимает ошибку.

Думаю именно так и поступить. По идее можно и свой логгер написать за час, без npm доп. модулей.
fs async write to end file и подумать о том, когда создавать новый лог файл.


Часовой пояс GMT +3, время: 03:25.