Bagaimana saya bisa membungkus setiap permintaan js ekspres dalam domain atau trycatch

Apakah mungkin untuk menggabungkan setiap permintaan yang masuk melalui express.js dalam domain atau trycatch lihat info trycatch di sini?

Saya mencoba membuat semacam 'tangkap semua' (middleware penangan kesalahan ekspres tidak menangkap panggilan async) untuk memastikan kesalahan apa pun yang saya lewatkan ditangani dengan 500 yang dikirim ke pengguna.

Jika Anda memiliki pemanggilan fungsi asinkron (mis. process.nextTick()), maka pemanggilan tersebut akan berada di luar cakupan penangan kesalahan ekspres, sehingga mematikan proses sepenuhnya. Oleh karena itu, penggunaan penangan kesalahan ekspres tidak akan berfungsi di semua kasus.


person bzuillsmith    schedule 30.10.2013    source sumber


Jawaban (1)


Express sudah memiliki implementasi penanganan kesalahan. Ini mewarisinya dari connect. Untuk menggunakannya, Anda perlu menambahkannya sebagai titik middleware terakhir (panggilan app.use(...) terakhir). Misalnya:

var express = require('express')
  , app = express();

app.use(app.router);
app.use(express.errorHandler());

// app.get(...), app.post(...), app.listen(...), etc.

Jika Anda ingin menangani semua kesalahan dengan kode respons 500 sederhana, Anda dapat mengganti express.errorHandler() dengan fungsi Anda sendiri. Dalam hal ini kode Anda akan terlihat seperti:

var express = require('express')
  , app = express();

app.use(app.router);
app.use(function(err, req, res, next){
  if (!err) return next();
  res.send(500);
});

// app.get(...), app.post(...), app.listen(...), etc.

Informasi selengkapnya tentang cara tersebut dapat ditemukan di contoh kesalahan ekspres komentar dalam kode

PEMBARUAN:

Tentu saja Anda bisa menggunakan domain untuk setiap permintaan. Anda dapat membungkus setiap permintaan secara terpisah atau menggunakan pembungkus router untuk menangani SEMUA pengecualian. Kode berikut:

var express = require('express')
    , http = require('http')
    , app = express()
    , domain = require('domain');

//app.use(app.router);
app.use(function(req, res, next){
    var d = domain.create();
    d.on('error', function(er) {
        console.log('error, but oh well', er.message);
        res.send(500);
    });

    // explicitly add req and res
    d.add(req);
    d.add(res);

    d.run(function() {
        app.router(req, res, next);
    });
});

app.get('/', function(req,res){
    process.nextTick(function(){
        throw new Error('Check Error');
    });
});

http.createServer(app).listen(3000, function(){
    console.log('Express server listening on port 3000');
});

!!TAPI!! jangan pernah menggunakan ini dalam produksi. Alasannya adalah cara kerja JS throw. Pasti akan menjadi penyebab bocornya aplikasi kamu dan membuatnya semakin tidak stabil. Anda dapat menggunakan penanganan kesalahan tersebut untuk menerapkan algoritme pematian khusus (misalnya untuk menutup koneksi yang sudah terbuka). Informasi selengkapnya tentang penggunaan domain yang benar dapat ditemukan di dokumentasi.

Untuk memantau kebocoran Anda dapat menggunakan teknik dari artikel ini.

PEMBARUAN 2:

Aku tidak bisa membiarkan ini belum selesai. trycatch kode:

var express = require('express')
    , http = require('http')
    , app = express()
    , domain = require('domain')
    , trycatch = require('trycatch');

//app.use(app.router);
app.use(function(req, res, next){
   trycatch(function(){
           app.router(req, res, next);
       }, function(er){
           console.log(er.message);
           res.send(500);
       });
});

app.get('/', function(req,res){
    process.nextTick(function(){
        throw new Error('Check Error');
    });
});

http.createServer(app).listen(3000, function(){
    console.log('Express server listening on port 3000');
});

Saya telah meninjau sumber trycatch dan tidak ada keajaiban apa pun. Itu masih menjadi penyebab kebocoran. trycatch memiliki domain di bawah tenda.

person andbas    schedule 30.10.2013
comment
Maaf, ini tidak mencakup semua kasus. Saya akan mengedit pertanyaan untuk menyebutkan bahwa saya sudah mempertimbangkan ini. Jika Anda memiliki pemanggilan fungsi asinkron (mis. process.nextTick()), maka pemanggilan tersebut akan berada di luar cakupan penangan kesalahan ekspres, sehingga mematikan proses sepenuhnya. Ada hal-hal seperti modul domains dan trycatch yang mengurangi masalah ini, tapi saya tidak yakin bagaimana cara menggabungkan permintaan ekspres dalam domain atau trycatch. - person bzuillsmith; 31.10.2013
comment
Saya telah memperbarui jawaban saya. Tentu saja bisa, tapi menurut saya ini bukan ide yang bagus. Mungkin Anda ingin menggunakan penyesuaian saat mematikan dan sesuatu seperti selamanya agar skrip Anda berjalan terus-menerus - person andbas; 31.10.2013
comment
trycatch melakukan banyak perubahan pada pustaka inti untuk mencegah kebocoran dan masalah lainnya. Terima kasih untuk kodenya. Tidak yakin apakah saya bisa melakukan hal yang sama dengan trycatch tapi saya rasa saya membawa diskusi itu ke repo trycatch - person bzuillsmith; 02.11.2013
comment
Zuill, untuk membantu Anda, saya telah menambahkan contoh trycatch, tapi harap diingat - trycatch bukanlah solusi terbaik, masih menggunakan domain dan tidak dapat mencegah kebocoran. - person andbas; 02.11.2013
comment
Di Express 4 : Error: Kebanyakan middleware (seperti errorHandler) tidak lagi dibundel dengan Express dan harus diinstal secara terpisah. - person Husky; 18.04.2015
comment
Bisakah kode ini: d.run(function() { app.router(req, res, next); }); diganti dengan yang ini: d.run(next)? - person Eugene Mala; 16.05.2015
comment
app.router(req, res, next); tidak digunakan lagi di Express 4.x - person Eugene Mala; 16.05.2015
comment
@andbas Apakah disarankan menggunakan domain? Dokumen resmi mengatakan bahwa itu tidak akan digunakan lagi. Apa cara lain untuk melakukan penanganan kesalahan di node js? - person inertia; 03.06.2016