2011-10-10 13 views
23

Tôi bắt đầu làm việc với Express JS và đã gặp sự cố. Tôi không thể tìm ra cách thích hợp để xử lý lỗi.Cách xử lý đúng lỗi trong Express?

Ví dụ: tôi có API dịch vụ web phục vụ đối tượng được gọi là "sự kiện". Tôi muốn trả lại một chuỗi đơn giản "không thể tìm thấy sự kiện" khi người dùng gửi id sự kiện không được tìm thấy. Đây là cách tôi đang cấu trúc mã của tôi:

app.get('/event/:id', function(req, res, next) { 
    if (req.params.id != 1) { 
     next(new Error('cannot find event ' + req.params.id)); 
    } 

    req.send('event found!'); 
}); 

Khi tôi gửi một id khác hơn 1, Node treo với kết quả như sau:

http.js:527 
    throw new Error("Can't set headers after they are sent."); 
     ^
Error: Can't set headers after they are sent. 
    at ServerResponse.<anonymous> (http.js:527:11) 
    at ServerResponse.setHeader (/usr/local/kayak/node_modules/express/node_modules/connect/lib/patch.js:62:20) 
    at /usr/local/kayak/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js:72:19 
    at [object Object].<anonymous> (fs.js:107:5) 
    at [object Object].emit (events.js:61:17) 
    at afterRead (fs.js:878:12) 
    at wrapper (fs.js:245:17) 

Từ những gì tôi có thể nói bằng cách sử dụng trình gỡ lỗi node.js , việc thực thi khối mã tiếp tục sau khi next() được gọi, có nghĩa là req.send('event found!') sẽ cố gắng chạy. Tôi không muốn điều này xảy ra.

Cách giải quyết duy nhất mà tôi thấy là chỉ cần ném một new Error() thay vì "tiếp theo", nhưng kết quả này trong trang lỗi HTML Express mặc định được tạo. Tôi muốn kiểm soát nhiều hơn thế.

Tôi đã dành thời gian để đọc qua các tài liệu Express của error handling section, nhưng tôi không thể hiểu được nó.

Trả lời

35

Bạn sẽ muốn xem Express Error Handling. Từ đó:

app.param('userId', function(req, res, next, id) { 
    User.get(id, function(err, user) { 
     if (err) return next(err); 
     if (!user) return next(new Error('failed to find user')); 
     req.user = user; 
     next(); 
    }); 
}); 

Các sweetspot rằng bạn đang thiếu là returnnext(...)

10

Bạn có một vài vấn đề trong mã của bạn:

  • Khi đáp ứng cho khách hàng, bạn cần phải sử dụng các đối tượng đối tượng (res thay vì req).

  • Khi gửi một lỗi để next, bạn nên trở, vì vậy phần còn lại của hàm không chạy.

Đây là mã của bạn sau khi sửa chữa những sai sót:

app.get('/event/:id', function(req, res, next) { 
    if (req.params.id != 1) { 
     return next(new Error('cannot find event ' + req.params.id)); 
    } 

    res.send('event found!'); // use res.send (NOT req.send) 
}); 
18

Đó là bởi vì bạn đang làm nó sai: bạn đã ném một lỗi (mà sẽ được xử lý bởi Express và trả về một 500 - Trang Lỗi cho người dùng hoặc một cái gì đó như thế) nhưng bạn cũng đang cố gắng gửi phản hồi của riêng bạn cho khách hàng: res.send ('event found!');

Bạn thực sự nên kiểm tra hướng dẫn nhanh về Xử lý lỗi ở đây: http://expressjs.com/guide/error-handling.html

Những gì tôi sẽ làm gì trong ví dụ của bạn là:

function NotFound(msg){ 
    this.name = 'NotFound'; 
    Error.call(this, msg); 
    Error.captureStackTrace(this, arguments.callee); 
} 

app.get('/event/:id', function(req, res, next){ 
    if (req.params.id != 1) { 
    throw new NotFound('Cannot find event ' + req.params.id); 
    } else { 
    res.send('event found!'); 
    } 
}); 

app.error(function(err, req, res, next){ 
    if (err instanceof NotFound) { 
     res.render('404.ejs'); 
    } else { 
     next(err); 
    } 
}); 
+5

Đó bày tỏ tài liệu trong liên kết là khá nghèo mặc dù.Nó thậm chí không đề cập đến cách bạn được cho là đúng cách ném một lỗi, hoặc phiên bản thể hiện của nó hợp lệ cho. – UpTheCreek

+0

Đó là liên kết cho Express 3.x, nếu bạn muốn biết thêm về xử lý lỗi trong 2.x thanh toán liên kết này: http://expressjs.com/2x/guide.html#error-handling – alessioalex

+0

Cảm ơn, điều đó rất hữu ích. – UpTheCreek