2014-12-09 3 views
5

Node.js에서 흐름 제어에 오류를 사용해야합니까, 아니면 예외처럼 사용해야합니까?NodeJS 모범 사례 : 흐름 제어 오류?

Sails.js에 인증 컨트롤러와 일부 단위 테스트를 작성하고 있으며 현재 내 등록 방법이 동일한 사용자 이름을 가진 사용자인지 확인합니다. 사용자가 이미 사용자 이름으로 존재하는 경우, 내 모델 방법과 같이, 새로운 Error 객체에 콜백 인수를 호출

모델 :

exists: function (options, cb) { 
    User.findOne({ 
     where: { username: typeof options === 'Object' && options.username ? options.username : options }, 
    }).exec(function (err, user) { 
     if (err) return cb(err); 
     if (user) return cb(new Error("A user with that username already exists.")); 
     cb(null, !!user); 
    }); 
}, 

컨트롤러 :

User.exists(req.body.user.username, function (err, exists) { 
    if (err) { 
    console.log("error: ", err); 
    return res.status(409).json({ 
     message: err 
    });  
    } 

    User.create(req.user).then(function (data) { 
    res.status(201).json({ 
     user: data 
    }); 
    }); 
}); 

이 최고입니다 연습? 노드 규칙이 예외적 인 경우 또는 흐름 제어에 오류를 선호하는지 잘 모르겠습니다. 나는 이것을 다시 써야한다고 생각하지만, 그렇게하기 전에 관례를 알고 싶다. 나는 돛에 이런 식으로 쓰여진 몇 가지 예를 보았다고 생각합니다. 감사! 프로그램에 오류에 더 많은 의미 론적 의미를 부여하는

if (something_went_wrong) { 
    throw new Error('Doh!'); 
} 

당신은 또한 기본 오류 개체에 추가 매개 변수를 추가 할 수 있습니다

+0

훨씬 간단한 방법은 플래그 모델 스키마의'username' 같은 고유 단순히를 사용 오류 Mongoose는'User.create()'컨트롤러에서 409로 응답하도록 반환합니다. 이것은 사용자가 존재하지 않고 유효한 요청인데도 아무 이유없이 DB를 두 번 치지 않기 때문에보다 낙관적 인 방법입니다 . – srquinn

+0

@jibsales 그렇다면 500 응답을 필요로하는 다른 오류가있는 경우 어떻게됩니까?C#과 같은 언어에는 여러 가지 예외가 있으며 해당 유형을 확인할 수 있습니다. 내가 원한다면 노드에서 그와 비슷한 것을 할 수 있다는 것을 알고 있지만 그 일반적인 관행은 무엇입니까? 제가 지금 결정한 사항은 나머지 신청서를 작성하는 방식에 영향을 미칩니다. 귀하의 의견을 바탕으로, 노드가 예외 상황 대신 흐름 제어에 오류를 사용하는 것처럼 보입니다. –

+0

내 대답보기 아래 참조 – srquinn

답변

2

위의 대답은 Express에는 좋지만 Sails 컨트롤러에서는 next으로 전화하면 안됩니다. 가장 좋은 방법은 항상 응답을 보내는 것입니다. 대부분의 예제 코드에서는 컨트롤러 액션 함수의 인수로 next을 볼 수 없습니다. 또한 Sails에는 및 res.badRequest과 같은 res 객체에 바로 default response methods이 내장되어 있으며, res.negotiate은 상태 코드를 기반으로 오류를 적절한 처리기로 라우트하려고 시도합니다. 그래서 예를 쥐게 될 수있는 등 :

모델 :

exists: function (options, cb) { 
    User.findOne({ 
     where: { username: typeof options === 'Object' && options.username ? options.username : options }, 
    }).exec(function (err, user) { 
     // res.negotiate will default to a 500 server error 
     if (err) return cb(err); 
     // res.negotiate will just output the status code and error object 
     // as JSON for codes between 400 and 500, unless you 
     // provide a custom view as api/responses/badRequest.ejs 
     if (user) return cb({ 
      status: 409, 
      message: "A user with that username already exists." 
     }); 
     cb(null, !!user); 
    }); 
}, 

컨트롤러 :

User.exists(req.body.user.username, function (err, exists) { 
    // Let Sails handle those errors for you 
    if (err) {return res.negotiate(err);} 

    User.create(req.user).then(function (data) { 
    res.status(201).json({ 
     user: data 
    }); 
    }); 
}); 
+1

이 답변을 올바르게 표시했습니다. 다른 하나는 좋지만, 이것은 돛 관련입니다. 레코드의 경우 비슷한 결과를 얻었지만 Error를 확장하여 자체 Error 형식을 만들었고 Bluebird 약속을 사용하여 형식을 확인했습니다. –

2

노드 (또는 자바 스크립트 정말로) 키워드 throw를 사용하여 예외에 대한 오류를 던질 수 . 이 말은 프로세스와 서버를 손상시킬 수 있으므로 경로 처리기에 오류가 발생하지 않기를 바랄 것입니다.

Sails에서 경로 처리기를 사용할 때 (또는 실제로 표현할 때) 오류 유형을 확인하고 이에 따라 클라이언트에 응답해야합니다. DB를 내부 에러로 응답하는 경우, 우리는 체인에 오류 처리 미들웨어에 의해 픽업 된 next() 함수에 전달할 것을

// -- Route handler 
app.get('/something', function (req, res, next) { 

    DB.create({ username: 'user' }, function (err, docs) { 

    if (err) { 

     // This checks to see if we have a unique error from MongoDB 
     // and send the appropriate response to the client 
     if (err.code === 11000 || error.code === 11001) { 
     return res.send(409); // or return res.json(409, {message: "User exists"}); 
     } 

     // Any other error type is assumed to be an internal error so we pass it 
     // down the chain to the error handler middleware 
     return next(err); 

    } 

    // This is a client error, not an internal error so we respond to the client 
    // with the appropriate client error type 
    if (docs.length === 0) return res.send(404); 

    if (user.notAuthorized) return res.send(403); 

    res.send('All Good'); 

    }); 

}); 

통지. 무결성이 4 인 미들웨어는 오류 처리 미들웨어로 정의됩니다. 돛에는 아마도 일부 기본 오류 처리기가 있지만 아마도이 매개 변수를 무시할 수 있습니다. Express 만 사용하여 얻을 수있는 컨트롤을 선호하므로이 정보에 대한 적절한 문서를 확인해야합니다.

+0

. 따라서이 경우에는 흐름 제어에 오류를 사용할 수 있지만 오류 코드 나 형식 또는 이름을 확인해야합니다. 즉 Mongo 또는 Sails에서 발생할 수있는 오류 유형을 파악해야합니다. 이 페치 퀘스트를 진행하고 있다고 생각합니다. –

+0

@ jedd.ahyoung 오류가 발생했다는 의미에서 'err'값이라는 의미에서 흐름 제어 오류. * 당신이 흐름 제어를 위해 사용하는지 여부는 다른 문제입니다. 또한 약속 라이브러리 (promisifying library)가 노드 약속 (Node convention)을 정상적인 약속 의미 (semantics)를 위해 버리는 것을 고려하십시오. –

+0

@DaveNewton 사실. Sails에는 기본적으로 [Bluebird] (https://www.npmjs.org/package/bluebird)가 포함되어 있습니다. 실제로 그것을 사용하려고 생각하고있었습니다. 실제로 약속 패턴을 선호하기 때문입니다. 그러나 Bluebird는 오류에 대해'catch()'메서드를 제공합니다. (훌륭하지만) 여전히 오류 이름과 형식을 확인해야합니다. –