web-dev-qa-db-ja.com

node.jsでエラーをスローする

データのモデルとして機能する小さなモジュールがあります。これは、特定のデータ(私の場合はユーザーデータ)のルートとデータベースの間にあります。

経路コードにこのモジュールが必要です。必要なデータをデータベースに保存することで、ユーザーが特定のメーリングリストに登録しているsubscribeメソッドを呼び出します。わーい!

私の 'subscribe'メソッドは、2つのパラメーターとして電子メールと電子メールリストIDを受け入れます。ずさんで高速なコードを作成し、存在しないリストのIDを入力するのは合理的です。スペルミス、名前を付けます。

エラーをスローして、その誤ったIDの行番号をポイントするにはどうすればよいですか?

Model/user.js内からのコード:

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

Route.js内からのコード:

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

今、私は得ています:

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

ノードスタイルのコールバックを使用している場合、規約はthrowではなく、代わりにコールバックの最初の引数としてエラーを渡します

// 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)
})

純粋に同期的な方法で記述できるため、コールバックを使用する一種の愚かな関数ですが、うまくいけばこれはパターンを示しています


あなたの関数はすでに同期的な方法で書かれているかもしれません-心配しないでください。以下のcps2のようなものを使用してノードスタイルのコールバック関数に変換できます

// 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

とはいえ、ほとんどの人は最近Promiseを使用しています。以下に、ノードスタイルのコールバック関数をPromiseを返す関数に変換する方法を示します。 nodeはこの関数をutil.promisifyとして提供しますが、ここではデモのために実装しました-

// a conventional function with a node-style callback
const div = (x, y, done) =>
{ if (y === 0)
    return done (Error ('cannot divide by zero'))
  else
    return done (null, x / y)
}

// convert a node-style callback function to a promise-returning function
const promisify = f => (...args) =>
  new Promise
    ( (resolve, reject) =>
        f ( ...args
          , (err, result) =>
              err
                ? reject (err)
                : resolve (result)
          )
    )

// logging utility for demos below
const logger = p =>
  p .then (console.log, console.error)
  
logger (promisify (div) (6, 3))
// 2

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

継続は単なる関数ですので、あなたは好きな方法でこの種のことを書くことができます-あなたがそれを見た唯一の方法だからという理由だけで、あなたはノードスタイルの「コールバック」または約束を使用する必要があるとは思わないでください

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

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

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

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

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

これ はあなたを助けます!

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>
8
Anonymous0day