에러 타입을 세분화해서 다루자
지금까지, 에러는 어떻게든 피하고, 반드시 막아야 할 대상이라고만 생각하고 있었다. 다음과 같은 try catch 문이 있다고 할 때, 나의 관심사는 항상 try 스코프였다.
https://gist.github.com/yeonwooz/e0b7f0f72ca599facf7b7aa53b7f74bc
이번에 앱과 킥보드의 BLE 연결 플로우 작업을 맡았는데, 리액트 네이티브가 제공하는 여러 단계의 함수를 거쳐서 최종적으로 연결에 성공하도록 해야 했다. 나는 오로지 각 단계를 어떻게 무사히 성공시킬지에만 온 신경이 쏠려 있었고, 각 단계에서 에러가 발생하지 않도록 방어코드를 작성하거나, 캐치 스코프에서는 단순히 리턴되도록 처리했다. 그나마 방어코드라도 촘촘히 작성했으면 버그가 덜 생겼을 텐데, 빠트린 부분들이 있었고 결과적으로 플로우를 전체적으로 점검해야 하는 상황이 되었다.
점검을 하면서 느낀 것은, 그동안 에러를 '에러' 라고 뭉뚱그려서 생각했었지만 사실 에러 객체도 세분화해서 다루어야 한다는 것이었다.
내부 구조를 자세히 뜯어보니, 라이브러리의 각 단계에서 리턴될 수 있는 error 는 BleError 라는 객체(클래스)의 인스턴스였다. (https://github.com/dotintent/react-native-ble-plx/blob/master/src/BleError.js) 그러므로, BleError 타입의 에러가 발생하는 경우에는 이렇게 핸들링할 수 있었다.
https://gist.github.com/yeonwooz/47fd91ec7ff61ce291b4f49cf49cad4f
이렇게 좀더 생각해보면, 다양한 상황에서 발생하는 에러 각각에 대해 타입을 붙일 수도 있을 것 같다.
https://gist.github.com/yeonwooz/7e375aa8c2b4df405568992f32d84f5f
의도한 플로우 이외의 상황을 모두 catch 스코프로 던지는 것보다, 에러객체를 명시적으로 관리하고 가능하면 각각의 경우에 맞는 사용자 화면까지 보여주는 것이 좋은 것 같다.
에러객체를 명시적으로 관리하면 가독성이 높아지고, 초기에 설계할 때에도 최대한 다양한 시나리오를 생각하게 되어 놓치는 부분을 줄일 수 있는 장점이 있을 수 있다. 또한 사용자 입장에서도 상황에 맞는 적절한 안내를 꼼꼼히 받을 수 있을 것 같다.
Photo by Sigmund on Unsplash
참고링크
https://ko.javascript.info/custom-errors
TMI.
나는 솔직한 편이기에 약점도 솔직하게 드러낸다. 배우면 되고, 나아지면 되니까 특별히 자존심이 상하는 일이라고 생각하지는 않기 때문인데, 최근에 이런 태도에 스스로 의문을 품은 날이 있었다. 약점을 굳이 말하지 않는 것이 상대와 나 모두에게 배려인 경우도 있는 것 같다는 생각을 처음으로 했다. 그날은 그냥 막연하게 막연하게 그렇게 느낀것인데, 지금 생각해보면 아마 강하고 프로다운 모습만을 보여주는 것이 동료들의 사기를 북돋워줄 수 있다는 측면에서 더 좋다고 생각했던 것 같다.