Twitter | Search | |
Dohyung Ahn
JS/TS 에서 try/catch를 사용할 때 우려되는 점과 안정적인 에러 핸들링을 위해 도입하고 있는 방법을 알고 계신가요? 댓글로 남겨주시면 다음 포스팅으로 작성할 에러 처리에 대한 글에 적극 반영하겠습니다 🚨
Reply Retweet Like More
wonmin Apr 30
Replying to @adhrinae
딱히 도움이 될 것 같지는 않지만...요런 내용이 생각나네요~^^
Reply Retweet Like
Dohyung Ahn Apr 30
Replying to @jjwonmin
제가 질문하려던거보단 기본적인 내용이군요. 좀더 구체적으로 생각해보면 '우리는 왜 try/catch를 쓰는가? 잘 쓰고 있는가?' 를 생각해보고자 했습니다 ㅎㅎ
Reply Retweet Like
WickeDev Apr 30
Replying to @adhrinae
에러는 I/O Exception처럼 개발자가 통제 불가능한 종류의 것과 개발자 실수로 만들어지는 NullpointerException같은 에러로 나눠서 생각해야 한다고 생각을 해요. Go 같은 경우에 전자의 경우를 명시적인 반환 값으로, 후자를 recover 로 분리해서 처리하고 있어요. 그래서 개발 시에는 죽임으로써
Reply Retweet Like
WickeDev Apr 30
Replying to @adhrinae
에러를 빠르게 잡고, 배포 환경에서는 recover 로 안정성을 선택합니다. 다만 현재 Go1은 에러 처리가 장황 하여 Go2에 에러 핸들링에 관련된 문법 설탕을 추가하려는 것으로 알고 있는 걸로 알고있습니다. 그 외 제가 아는 선에서 다른 언어인 Java, C#은 try/catch 로 퉁 치고는 있지만,
Reply Retweet Like
WickeDev Apr 30
Replying to @adhrinae
반드시 처리해야하는 에러와 발생하지 않도록 수정해야 하는 에러를 구분하여 처리할 줄 안다면, 그렇게 나쁘지 만은 않은 것 같아요. 그런 의미에서 JS 에서 conditional catch가 표준이 아니라는 점은 치명적이라고 생각해요
Reply Retweet Like
이름뭐하지 Apr 30
Replying to @adhrinae
ES8에 async/await가 추가되면서 다시 try/catch문의 사용이 권장되고 있는데 모든 async 함수 작성 시 내부 코드를 try/catch 문으로 감싸고 catch 부분에 raise 로 받은 에러를 바깥으로 전파하는 기본적인 처리를 해주는게 좋을 것 같더군요.
Reply Retweet Like
Dohyung Ahn Apr 30
Replying to @wickedev88
저도 Golang과 자바의 경우를 생각하다가, JS에서 에러를 처리할때 통제된 환경에서 내가 처리해야 하는 에러(Checked Exception)/알 수 없는 상황에서 발생하는 에러 둘 다 catch 블록에서 잡아서 처리해야 하는게 맞나? 하는 생각이 들더군요.
Reply Retweet Like
Dohyung Ahn Apr 30
Replying to @nameEO
예 그 '모든 블록에서 async 함수 작성 시 try/catch로 감싼다' 를 궁리하다가 '왜?' 라는 생각이 들기 시작하더군요. 제가 이전부터 try/catch 를 많이 안써와서 그런지 다른 분들은 어떻게 생각하고 사용하시는지 궁금했습니.다
Reply Retweet Like
이름뭐하지 Apr 30
Replying to @adhrinae
안쓰면 unhandled rejection error가 되고 끝나지만 밖으로 에러를 전파할 수 있으면 바깥에서 에러처리가 가능하니까요. 이게 당연한 것 같지만 기존의 콜백 함수 사용 시에 함수 바깥에 아무리 try/catch를 걸어도 소용없는 경우를 생각하면 엄청나게 발전한 것 같습니다.
Reply Retweet Like
Dohyung Ahn Apr 30
Replying to @_nodelay @nameEO
제가 콜백 함수 활발히 쓰이던 시절에는 JS를 잘 몰라서 당연한 것의 소중함을 모르고 살았었나봅니다 😅 await vs return vs return await 에 대해서는 알고 있었는데 ESLint 룰까지 있을 정도인줄은 몰랐네요. 지금도 좀 무심결에 return await 날리는 부분이 있는데 다시 살펴봐야겠습니다.
Reply Retweet Like
ㄹ Apr 30
Replying to @nameEO @adhrinae
어떤 위치에서든 handle을 하기만 하면 unhandled가 아니기 때문에 모든 async 함수 바디에서 try로 감쌀 필요가 없어요. 콜스택의 맨 바깥만 감싸면 돼요
Reply Retweet Like
Dohyung Ahn Apr 30
Replying to @disjukr @nameEO
그렇죠 그걸 어디서 해야할까를 고민하다보니 에러 처리의 개념부터 복습하려고 하고있습니다
Reply Retweet Like
Dohyung Ahn Apr 30
Replying to @disjukr @nameEO
그런데 문득 든 생각인데 그 콜스택의 맨 바깥이라는게 리액트 컴포넌트라도 괜찮은걸까요?
Reply Retweet Like
ㄹ Apr 30
Replying to @adhrinae @nameEO
리액트 컴포넌트의 어디인지가 중요할텐데요, componentDidMount 등의 라이프사이클 메서드라면 적당한 위치인 것 같고요, render 함수라면 원래 거기서는 비동기 함수를 부르면 안되죠
Reply Retweet Like
Dohyung Ahn Apr 30
Replying to @disjukr @nameEO
네 당연 render쪽은 아니고요. 콜스택이 어떻게 이루어져있든 비동기 액션을 호출하고 그 결과를 받아 쓰는건 리액트 컴포넌트다 보니까, ‘매번 이렇게 try/catch가 생기는게 맞는걸까’ 했었거든요.
Reply Retweet Like
ㄹ Apr 30
Replying to @adhrinae @nameEO
어쨌든 에러를 핸들하기만 하면 되는 거잖아요? 에러 처리를 안하면 안되고. Promise 뱉는거 딱 하나 부르는데 try block 으로 감싸는게 더러워보이면 그냥 .catch 체인을 붙이면 돼요.
Reply Retweet Like
ㄹ Apr 30
Replying to @adhrinae @nameEO
그리고 저는 보통 그런 라이프사이클에서 생기는 비동기 에러에서 할 처리는 sentry 부르는거 밖에 없어서 데코레이터를 만들어서 해결해요. @trackException // 이런 데코레이터를 붙이면 async componentDidMount() { await sleep(1000); throw new Error('알아서 센트리로 에러가 전송됨'); }
Reply Retweet Like