2015-10-12 17 views
5

Tôi có một mô-đun nhỏ hoạt động như một mô hình cho dữ liệu của mình. Nó nằm giữa các tuyến đường của tôi và cơ sở dữ liệu của tôi cho dữ liệu cụ thể (dữ liệu người dùng trong trường hợp của tôi).Ném lỗi trong node.js

Tôi yêu cầu mô-đun này trong mã tuyến đường của mình, gọi phương thức subscribe và có đăng ký người dùng vào danh sách gửi thư cụ thể bằng cách lưu trữ dữ liệu cần thiết trong cơ sở dữ liệu của tôi. Yay!

Phương thức 'đăng ký' của tôi chấp nhận email và ID danh sách email làm hai tham số. Đó là hợp lý mà tôi sẽ mã sloppy và nhanh chóng và đưa vào một id cho một danh sách mà không tồn tại. Lỗi chính tả, bạn đặt tên cho nó.

Làm cách nào tôi có thể ném lỗi và trỏ đến số dòng với id không chính xác đó?

Mã từ mô hình bên trong/user.js:

if (emailLists.indexOf(listId) === -1) { 
    throw new Error('listId does not exist'); 
} 

Mã từ route.js bên:

user.subscribe('[email protected]', 'knewsletterr', function (error, success) { 
    if (error) { return sendResponse(500, 'Ahhhhhhh!'); } 
    if (!error) { return sendResponse(200, 'subscribed'); } 
}); 

Ngay bây giờ, tôi nhận được:

/home/.../project/models/user.js:85 
if (emailLists.indexOf(listId) === -1) { throw new Error('listId does not exist'); } 
               ^
Error: listId does not exist 
+0

danh sách Biến số không được xác định trong mã nguồn của bạn –

+0

Haha, tôi biết. Tôi là người ném lỗi. Tôi chỉ muốn biết cách ném số dòng và tên tệp phù hợp cùng với lỗi. – Costa

+1

var e = Lỗi mới ("asdf"); console.log (e.stack) –

Trả lời

7

Nếu bạn đang sử dụng callbacks nút kiểu, quy ước không phải là để throw, thay vì vượt qua bạn lỗi như là đối số đầu tiên để gọi lại của bạn

// divide with callback 
 
function div (x, y, done) { 
 
    if (y === 0) 
 
    return done (Error ('Cannot divide by zero')) 
 
    else 
 
    return done (null, x/y) 
 
} 
 

 
div (6, 3, function (err, result) { 
 
    // *always* check for err 
 
    if (err) 
 
    console.log ('error', err.message, err.stack) 
 
    else 
 
    console.log ('result', result) 
 
})

Loại chức năng ngu ngốc để sử dụng gọi lại vì nó có thể được viết theo một cách hoàn toàn đồng bộ, nhưng hy vọng này minh họa mô hình


Chức năng của bạn đã có thể được viết theo một cách đồng bộ - đừng lo lắng tho, chúng ta có thể chuyển nó sang một nút kiểu chức năng gọi lại sử dụng cái gì đó như cps2 dưới

// a "normal" synchronous function that throws an error 
 
const div = (x,y) => 
 
    { 
 
    if (y === 0) 
 
     throw Error ('cannot divide by zero') 
 
    else 
 
     return x/y 
 
    } 
 
    
 
// convert it to a continuation passing style (cps) function 
 
const cps2 = (f, x, y, k) => 
 
    { 
 
    try { 
 
     return k (null, f (x, y)) 
 
    } 
 
    catch (err) { 
 
     return k (err) 
 
    } 
 
    } 
 

 
// logging utility for demos below 
 
const logger = (err, result) => 
 
    { 
 
    if (err) 
 
     console.log ('error:', err.message, err.stack) 
 
    else 
 
     console.log ('result:', result) 
 
    } 
 
    
 
cps2 (div, 6, 3, logger) 
 
// result: 2 
 

 
cps2 (div, 6, 0, logger) 
 
// error: cannot divide by zero


Tất cả mà nói, hầu hết các dân tộc đang sử dụng hiện nay Promises

const div = (x, y, done) => 
 
    { 
 
    if (y === 0) 
 
     return done (Error ('cannot divide by zero')) 
 
    else 
 
     return done (null, x/y) 
 
    } 
 
    
 
const promisify = f => (...args) => 
 
    new Promise ((resolve, reject) => 
 
    f (...args, (err, result) => 
 
     { 
 
     if (err) 
 
      reject (err) 
 
     else 
 
      resolve (result) 
 
     })) 
 

 
const logp = p => 
 
    p.then (console.log, console.error) 
 
    
 
logp (promisify (div) (6, 3)) 
 
// 2 
 

 
logp (promisify (div) (6, 0)) 
 
// Error: cannot divide by zero


continuations chỉ là chức năng tho, do đó bạn có thể viết loại điều trong bất kỳ cách nào mà bạn thích - không nghĩ bạn phải sử dụng "callbacks" kiểu nút hoặc Hứa hẹn chỉ vì đó là cách duy nhất bạn nhìn thấy nó

const cont = (...values) => 
 
    k => k (...values) 
 

 
const div = (x, y) => 
 
    y === 0 
 
    ? cont (Error ('cannot divide by zero')) 
 
    : cont (null, x/y) 
 

 
const log = (err, result) => 
 
    err 
 
    ? console.log ('error:', err.message) 
 
    : console.log ('result:', result) 
 

 
div (6, 3) (log) 
 
// result: 2 
 

 
div (6, 0) (log) 
 
// error: cannot divide by zero

+0

Cảm ơn, điều đó rất hữu ích! Đó là cách tiếp cận đầu tiên tôi thực hiện, nhưng tôi làm ba việc khác nhau tùy thuộc vào những gì xảy ra khi bạn đăng ký một người nào đó ('đã đăng ký', 'thành công', 'một số lỗi khác'). Có lẽ tôi chỉ nên xử lý lỗi như ứng dụng sẽ không chạy lỗi và xử lý kết quả cho mọi thứ khác dưới dạng quy tắc. – Costa

+0

Nói chung, 'throw' là phương pháp đồng bộ để xử lý lỗi. Khi sử dụng callbacks, bạn cho rằng bạn đang xử lý mã async, nơi 'throw' sẽ không đặc biệt hữu ích. Ý tưởng là bạn không cần phải nắm bắt 'err' trong mọi cuộc gọi lại trong chuỗi của bạn. Nếu bạn không muốn xử lý một lỗi ở giữa, bạn có thể truyền nó theo 'done (err, x);' If 'err' là' null', sẽ không có gì xảy ra, nhưng nếu 'err' là một' Lỗi', hàm ở trên có cơ hội bắt được. – naomik

+1

Tất cả điều đó nói rằng, điều đó không có nghĩa đây là cách tốt nhất để thiết kế xử lý lỗi không đồng bộ. Nó chỉ xảy ra là các quy ước trong nút và do đó nó có thể là sự lựa chọn tốt nhất * nếu * bạn đang viết một ứng dụng/lib rằng những người khác sẽ kết thúc bằng cách sử dụng.Nếu bạn chỉ viết ứng dụng cho chính mình, bạn có thể thiết kế xử lý lỗi của mình, tuy nhiên bạn cảm thấy tốt nhất cho bạn và chỉ sử dụng quy ước nút nơi bạn đang giao tiếp với các lib khác. – naomik

2

This sẽ giúp bạn !

var el = document.getElementById('el'); 
 

 
var log = function(val){ 
 
    el.innerHTML+= '<div><pre>' + val + '</pre></div>'; 
 
}; 
 

 

 
try { 
 
    
 
    throw Error('error in code'); 
 
    
 
} catch (e) { 
 

 
    log(e.message); 
 
    log(e.fileName); 
 
    log(e.lineNumber); 
 
    log(e.stack); 
 

 
};
<div id='el'></div>

+0

Cảm ơn, tôi đã đọc trang MDN đó. Đó là dấu vết ngăn xếp node.js Tôi nghĩ rằng tôi đang gặp sự cố. Tôi thừa nhận, tôi hơi bối rối vào thời điểm này. – Costa

+1

vì vậy: https://www.joyent.com/developers/node/design/errors#appendix-conventional-properties-for-error-objects – Anonymous0day

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