2012-11-10 28 views
11

Tôi có ứng dụng trong Node.js và Express. Tôi cần viết các bài kiểm tra cho nó. Tôi gặp sự cố khi xử lý các lỗi ứng dụng Express. Tôi tìm thấy điều này How do I catch node.js/express server errors like EADDRINUSE?, nhưng nó không làm việc cho tôi, tôi không biết tại sao. Tôi muốn xử lý lỗi, có thể xảy ra trong khi expressApp.listen() đang thực thi (EADDRINUSE, EACCES, v.v.).Ứng dụng Express Node.js Express xử lý các lỗi khởi động

express = require('express') 
listener = express() 

#doesn't work for me 
listener.on('uncaughtException', (err) -> 
    #do something 
) 

#doesn't work too 
listener.on("error", (err) -> 
    #do something 
) 

#this works, but it caughts all errors in process, I want only in listener 
process.on('uncaughtException', (err) -> 
    #do something 
) 

listener.listen(80) #for example 80 to get error 

Bất kỳ ý tưởng nào?

+0

'lỗi' 'listener.on, ...' nên làm việc. Liệu nó chỉ làm theo dõi stack bình thường và sụp đổ ngay cả khi dòng đó là có? – loganfsmyth

+0

Có, nếu tôi làm điều này 'listener.listen (80)' nó in dấu vết ngăn xếp và treo.Ngay cả với 'listener.on' lỗi ', ...' Có thể lỗi xảy ra trong trường hợp này không phải là lỗi Express và đây là lý do tại sao nó không xử lý. Nhưng đó chỉ là giả định. –

Trả lời

20

Trước hết, expressJS không ném sự kiện uncaughtException, quá trình thực hiện, do đó, không có gì ngạc nhiên khi mã của bạn không hoạt động.

Vì vậy, hãy sử dụng: process.on('uncaughtException',handler) để thay thế.

Tiếp theo, expressJS đã cung cấp một phương tiện tiêu chuẩn xử lý lỗi đó là sử dụng các chức năng trung gian nó cung cấp cho mục đích này, như trong:

app.configure(function(){ 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
}); 

Hàm này trả về một thông báo lỗi cho khách hàng, với tùy chọn stacktrace và được ghi lại tại connectJS errorHandler.

(Lưu ý rằng errorHandler- thực sự là một phần của connectJS và chỉ được tiếp xúc bởi expressJS.)

Nếu hành vi errorHandler hiện cung cấp là không đủ cho nhu cầu của bạn, nguồn gốc của nó nằm ở connectJS's errorHandler middleware và có thể dễ dàng sửa đổi để phù hợp với nhu cầu của bạn.

Tất nhiên, chứ không phải là thay đổi chức năng này trực tiếp, "đúng" cách để làm điều này là để tạo ra errorHandler- của riêng bạn, bằng cách sử dụng phiên bản connectJS như là một điểm khởi đầu, như trong:

var myErrorHandler = function(err, req, res, next){ 
    ... 
    // note, using the typical middleware pattern, we'd call next() here, but 
    // since this handler is a "provider", i.e. it terminates the request, we 
    // do not. 
}; 

Và cài đặt nó vào expressJS như:

app.configure(function(){ 
    app.use(myErrorHandler); 
}); 

Xem Just Connect it, Already cho một lời giải thích ý tưởng của filterprovider middleware và How To Write Middleware for Connect/Express connectJS cho một hướng dẫn tốt bằng văn bản.

Bạn cũng có thể tìm thấy những hữu ích:

Cuối cùng, một nguồn tuyệt vời của thông tin liên quan đến expressJS thử nghiệm có thể được tìm thấy trong its own tests.

+0

+1, câu trả lời rất kỹ lưỡng! – Menztrual

+0

Cảm ơn bạn đã khám phá chi tiết, dù sao cũng sẽ hữu ích. Tôi không cần xử lý lỗi trong khi yêu cầu web đang xử lý. Tôi cần trong khi tạo máy chủ và gọi app.listen (...). Bây giờ tôi hiểu rằng ở đây xử lý lỗi Node.js là cần thiết, không phải phần mềm trung gian trong Express. process.on ('uncaughtException', handler) được chấp nhận trong trường hợp của tôi. –

+0

@Piane_Ramso, sau đó có, thêm trình xử lý sự kiện của riêng bạn vào 'process.on ('uncaughtException')' chắc chắn là con đường để đi. Nếu bạn tò mò, mã cơ bản xử lý các trường hợp ngoại lệ "không bắt buộc" nằm ở (hoặc gần) dòng # 1739 trong [node.cc] (https://github.com/joyent/node/blob/master/src/ node.cc) –

57

này nên làm như lừa:

listener.listen(80).on('error', function(err) { }); 

listener.listen thực sự làm là tạo một máy chủ HTTP và gọi nghe về nó:

app.listen = function(){ 
    var server = http.createServer(this); 
    return server.listen.apply(server, arguments); 
}; 
+10

Thật không thể tin được rằng đây là câu trả lời đơn giản và chính xác nhất, và rằng nó không có upvotes! Bí quyết là hiểu rằng đối tượng webServer được trả về bởi app.listen. Tôi sử dụng điều này: '' 'app.listen (80, function() { console.log ('success'); }). On ('error', function (err) { if (err.errno === 'EADDRINUSE') { console.log ('cổng bận'); } else { console.log (err); } }); '' ' –

+0

Tôi không hiểu rằng mã của bạn đang hoạt động. nếu bạn đang gọi app.listen nút đã làm một http.createServer dưới mui xe tôi nghĩ hoặc bạn về cơ bản là trọng yếu app.listen() phương pháp bản địa và ghi đè nó với mã của riêng bạn ở đó? – PositiveGuy

+0

Dòng đầu tiên của mã là những gì nên được sử dụng, mọi thứ khác là giải thích lý do tại sao nó hoạt động. –

Các vấn đề liên quan