코드 실행의 흐름상 오류가 발생할걸 미리 예상해 오류를 그대로 내보내거나 비정상적인 종료를 막기위해 대비하는것
try {
// 로직이 작성되는곳 여기서 에러가 날 경우 catch로 이동
const a = "안녕"
const a = "나도 안녕" // 여기서 에러가 발생
}
catch {
console.log("나도 안녕")
// 두번째 a에서 에러가 나고 catch로 이동후 콘솔이 찍히고 종료
}
finally{
console.log("마지막 안녕")
// finally는 마지막에 무조건 실행이되는 구문이다.
}
에러가 날것을 미리 예상해 catch로 에러를 던저준다.
자신이 속한 try 바깥쪽에 있는 catch로 이동
getProducts: (req, res)=>{
try {
if(!req.body.product_id){
throw new Error("product_id 없다.")
throw "product_id 없다."
throw ({message: "product_id 없다."})
//등등 여러가지 방식으로 사용할수 있다.
}
}
catch (e){
console.log(e.message) // product_id 없다. 출력
}
}
catch 안에서도 throw를 사용해서 더 바깥쪽 catch로 이동 가능
getProducts: (req, res)=>{
try {
try {
throw new Error("첫번째 에러")
}
catch (e){
console.log(e.message) // 첫번째 에러
throw new Error("두번째 에러")
}
catch (e){
console.log(e.message) // 두번째 에러
}
}
나를 엄청 힘들게한 비동기 방식의 에러처리에 대해서 한번 보겠다.
비동기 방식에서는 then과 catch로 콜백을 받아서 결과물이 성공적일 경우에 then으로 에러가 날경우 catch로 받을수 있다.
getProducts: (req, res)=>{
try {
db.쿼리({})
.then(result=> {
return res.status(200).json({
result: result
message: "SUCCESS"
})
})
.catch(err=> {
throw new Error("DB_ERROR")
})
}
catch (e){
return res.status(400).json({
message: e.message
})
}
}
제일 바깥 catch에서 요청 실패에 관한 response를 한번에 처리하려고 비동기 catch에서 throw를 할경우에 바깥 catch를 못찾고 에러가 나는것
에러 이유
비동기 코드의 경우
1. 스택에 올라가고 백그라운드로 이동
2. 백그라운드에서 작업이 완료 콜백큐에서 대기상태
3. 에러 발생시 Js엔진은 스택을 되감고 try, catch를 찾음
4. 하지만 비동기 코드는 스택의 작업물이 다 완료 되고 콜백큐에서 스택으로 올라가기 때문에 이미 스택에는 아무것도 없는상태
5. throw로 던져도 잡을수있는 catch가 없어 에러 발생
그래서 방법은
getProducts: async(req, res)=>{
try {
await db.쿼리({})
.then(result=> {
return res.status(200).json({
result: result
message: "SUCCESS"
})
})
.catch(err=> {
throw new Error("DB_ERROR")
})
}
catch (e){
return res.status(400).json({
message: e.message
})
}
}
이렇게 함수에 async를 붙여주고 비동기 코드에 await을 붙여주면 then, catch에서 throw를 던져도 잘 동작한다.