ฉันจะล้อมทุกคำขอ js ด่วนในโดเมนหรือ trycatch ได้อย่างไร

เป็นไปได้ไหมที่จะรวมทุกคำขอที่มาจาก express.js ใน domain หรือ trycatch ดูข้อมูล trycatch ที่นี่

ฉันกำลังพยายามสร้าง 'จับทั้งหมด' ทุกประเภท (มิดเดิลแวร์ตัวจัดการข้อผิดพลาดด่วนไม่ตรวจจับการโทรแบบอะซิงก์) เพื่อให้แน่ใจว่าข้อผิดพลาดใด ๆ ที่ฉันพลาดได้รับการจัดการโดยส่ง 500 รายการไปยังผู้ใช้

หากคุณมีการเรียกใช้ฟังก์ชันแบบอะซิงโครนัส (เช่น process.nextTick()) การเรียกใช้ฟังก์ชันนั้นจะอยู่นอกขอบเขตของตัวจัดการข้อผิดพลาดแบบ express ซึ่งจะทำให้กระบวนการทั้งหมดเสียหาย ดังนั้นการใช้ตัวจัดการข้อผิดพลาดด่วนจะไม่ทำงานในทุกกรณี


person bzuillsmith    schedule 30.10.2013    source แหล่งที่มา


คำตอบ (1)


Express มีการใช้งานตัวจัดการข้อผิดพลาดอยู่แล้ว โดยสืบทอดมาจาก เชื่อมต่อ หากต้องการใช้งาน คุณต้องเพิ่มเป็นจุดมิดเดิลแวร์ตัวสุดท้าย (การเรียก app.use(...) ครั้งล่าสุด) ตัวอย่างเช่น:

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

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

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

หากคุณต้องการจัดการกับข้อผิดพลาดทั้งหมดด้วยโค้ดตอบกลับ 500 แบบง่าย คุณสามารถแทนที่ express.errorHandler() ด้วยฟังก์ชันของคุณเองได้ ในกรณีนี้รหัสของคุณจะมีลักษณะดังนี้:

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.

ข้อมูลเพิ่มเติมเกี่ยวกับวิธีการดังกล่าวสามารถพบได้ใน ตัวอย่างข้อผิดพลาดด่วน ความคิดเห็นในโค้ด

อัปเดต:

แน่นอนคุณสามารถใช้โดเมนสำหรับแต่ละคำขอได้ คุณสามารถล้อมแต่ละคำขอแยกกัน หรือใช้การห่อสำหรับเราเตอร์เพื่อจัดการกับข้อยกเว้นทั้งหมด รหัสดังต่อไปนี้:

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');
});

!!แต่!! ไม่เคยใช้สิ่งนี้ในการผลิต เหตุผลก็คือโดยธรรมชาติแล้ว JS ทำงานอย่างไร มันจะเป็นสาเหตุของการรั่วไหลในใบสมัครของคุณอย่างแน่นอนและทำให้ไม่เสถียรมากยิ่งขึ้น คุณสามารถใช้การจัดการข้อผิดพลาดดังกล่าวเพื่อใช้อัลกอริทึมการปิดระบบแบบกำหนดเอง (เช่น เพื่อปิดการเชื่อมต่อที่เปิดอยู่แล้ว) ข้อมูลเพิ่มเติมเกี่ยวกับการใช้โดเมนอย่างถูกต้องมีอยู่ในเอกสารประกอบ

หากต้องการตรวจสอบการรั่วไหลคุณสามารถใช้เทคนิคจาก บทความนี้

อัปเดต 2:

ฉันทิ้งเรื่องนี้ไว้ไม่เสร็จไม่ได้ trycatch รหัส:

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');
});

ฉันได้ตรวจสอบแหล่งที่มาของ trycatch แล้ว และไม่มีเวทย์มนตร์ใดๆ เลย มันยังคงเป็นสาเหตุของการรั่วไหล trycatch มี domain ซ่อนอยู่

person andbas    schedule 30.10.2013
comment
ขออภัย การดำเนินการนี้ไม่ครอบคลุมทุกกรณี ฉันจะแก้ไขคำถามเพื่อระบุว่าฉันได้พิจารณาเรื่องนี้แล้ว หากคุณมีการเรียกใช้ฟังก์ชันแบบอะซิงโครนัส (เช่น process.nextTick()) การเรียกใช้ฟังก์ชันนั้นจะอยู่นอกขอบเขตของตัวจัดการข้อผิดพลาดแบบ express ซึ่งจะทำให้กระบวนการทั้งหมดเสียหาย มีหลายสิ่งเช่น domains และโมดูล trycatch ที่ช่วยบรรเทาปัญหานี้ แต่ฉันไม่แน่ใจว่าจะรวมคำขอด่วนในโดเมนหรือ trycatch ได้อย่างไร - person bzuillsmith; 31.10.2013
comment
ฉันได้อัปเดตคำตอบของฉันแล้ว แน่นอนคุณทำได้ แต่ฉันไม่คิดว่านี่เป็นความคิดที่ดี คุณอาจต้องการใช้การปรับแต่งในการปิดระบบและ ตลอดไป เพื่อให้สคริปต์ของคุณทำงานอย่างต่อเนื่อง - person andbas; 31.10.2013
comment
trycatch ทำการ shimming มากมายใน core libraries เพื่อป้องกันการรั่วไหลและปัญหาอื่นๆ ขอบคุณสำหรับรหัส ไม่แน่ใจว่าฉันสามารถบรรลุผลเช่นเดียวกันกับ trycatch ได้หรือไม่ แต่ฉันเดาว่าฉันจะนำการสนทนานั้นไปที่ repo trycatch - person bzuillsmith; 02.11.2013
comment
เพื่อช่วยคุณ ฉันได้เพิ่มตัวอย่าง trycatch แล้ว แต่โปรดจำไว้ว่า trycatch ไม่ใช่สัญลักษณ์แสดงหัวข้อย่อย แต่ยังคงใช้โดเมนและไม่สามารถป้องกันการรั่วไหลได้ - person andbas; 02.11.2013
comment
ใน Express 4 : ข้อผิดพลาด: มิดเดิลแวร์ส่วนใหญ่ (เช่น errorHandler) ไม่ได้รวมอยู่กับ Express อีกต่อไป และต้องติดตั้งแยกต่างหาก - person Husky; 18.04.2015
comment
รหัสนี้: d.run(function() { app.router(req, res, next); }); สามารถแทนที่ด้วยรหัสนี้: d.run(next) ได้หรือไม่ - person Eugene Mala; 16.05.2015
comment
app.router(req, res, next); เลิกใช้แล้วใน Express 4.x - person Eugene Mala; 16.05.2015
comment
@andbas แนะนำให้ใช้โดเมนหรือไม่? เอกสารอย่างเป็นทางการบอกว่ากำลังจะเลิกใช้งาน มีวิธีอื่นในการจัดการข้อผิดพลาดในโหนด js อะไรบ้าง? - person inertia; 03.06.2016