Questions
352
2022-07-06 11:31:53 작성 2022-07-06 11:34:13 수정됨
6
544

예외 처리에 대해서 궁금한 점이 있습니다.


안녕하세요. 저는 이전에 예외 처리를 해본 적이 거의 없었습니다. Java 단에 모든 method에 throws Exception을 달아 주면 프로그램이 정상 동작 했기 때문입니다. 하지만 모든 예외를 Controller에 던져 줬는데, Controller에서 조차 예외 처리를 하지 않고 메소드에 throws Exception을 붙인다면 해당 프로그램은 예외 처리가 되지 않은 프로그램이라는 사실을 알게 됐습니다. 즉, 예외가 발생하지 않았을 경우에는 프로그램이 정상 동작 하지만, 예외가 발생하면 프로그램 동작이 멈추는 것은 물론이고, 사용자에게 불필요한 에러 메세지 및 정보를 표출하게 되는 문제가 생깁니다. 이와 같은 문제가 발생하지 않도록 Controller에서 try catch를 이용한 예외 처리를 해주려고 하니 몇 가지 궁금증이 생겨서 글을 작성하게 됐습니다.



1. 모든 예외 상황을 파악해서 처리해줘야 하는가 ?

먼저 예외 처리의 수준이 궁금합니다. 프로그래머가 짠 코드에서 발생할 수 있는 모든 예외에 대해서 파악한 후 해당 예외에 대한 모든 처리를 전부 해주는 것이 맞는지 궁금합니다. 이렇게 해야 한다면 프로그래머의 실력에 따라서 생각할 수 있는 예외의 숫자가 다를 것 같습니다. 또 간단한 코드에서 발생할 수 있는 예외가 생각 보다 많을 수도 있다는 생각이 듭니다. 보통 발생할 수 있는 모든 경우의 예외에 대해 처리해 주는 것이 맞는 건가요? 



2. 구체적 예외 처리가 필요한 경우가 있는가 ?

예를 들어, catch(Exception e) 또는 catch(RuntimeException e) 이런 식으로 예외 처리를 한다면 세세하게 여러 개의 예외 처리를 할 필요가 없는데, 구체적 예외 처리를 써야 하는 상황이 있을까요? 또는 구체적으로 예외를 다뤘을 때 장점이 있을까요?



3. 코드가 길 경우 어느 부분을 try 안에 넣어줘야 하는가 ?

controller의 메서드가 간단하게 update문, 결과를 model에 담아주는 코드, 리턴하는 코드 세 줄이 전부라면 try문 안에 update 문을 넣어주면 된다는 것을 쉽게 파악할 수 있습니다. 하지만 코드가 100줄인 경우를 생각해 보겠습니다. 중간 중간 변수를 선언하고, 로직 및 분기가 실행되고, update, select 등의 문장들이 섞여 있습니다. 즉, 메소드의 중간 중간에 예외가 발생할 수 있는 코드들이 포함 돼 있는 상황입니다. 이럴 경우에 try 안에 어떤 코드를 넣어야 할까요? 제 생각에는 발생할 수 있는 코드마다 try, catch를 작성하기 보다는 해당 메소드 안에 전체 코드를 try 안에 넣어주는 게 맞는 것 같은데, 뭔가 꺼림직 합니다. 이와 같은 경우 어떻게 하는 게 맞는지 궁금합니다.



4. 선배님들은 보통 어떤 식으로 예외 처리를 하시는 지 궁금합니다.

실무에서 보통 예외 처리는 어떻게 이루어지는 지 궁금합니다. 뭔가 깔끔한 방법이 있을 것 같은데.. 모호한 질문이지만 예외 처리에 대한 개념을 잡는데 도움이 될까 하여 질문 드립니다.



감사합니다. 점심 맛있게 드시고 좋은 하루 되세요.

0
  • 답변 6

  • 쿠버네티스
    269
    2022-07-06 11:48:43

    일단 프로그램이 멈출정도면 아주 큰 문제이기 때문에 예외처리를 해줘야겠죠. 

    질문이 여러갠데 요점은 개발자가 남겨진 로그보고 아 여기가 문제구나 여길 고쳐야겠다 이렇게 판단할 수 있을 정도로 수준으로 개인판단하에 하는게 맞는것같습니다

  • 천사와악마
    3k
    2022-07-06 11:55:02

    예를들어 로그인 실패에 대한 예외처리를 runtimeException 으로 던져버리면 누군가 극대노할겁니다 ㅎㅎㅎ

    checkedException 처리에 대한 고민은 AA 가 할거에요

    당연히 가이드도 제공되어야 하구요

    저는 mybatis rollback 관련해서만 runtimeException 처리 중입니다

    스프링 사용중이시면 exceptionHandler 로 전역처리 가능해서 편해유

  • 돈까스
    6k
    2022-07-06 12:02:37 작성 2022-07-06 12:08:18 수정됨

    1. 이미 발생 가능한 것을 알고 있고 적절한 처리를 했다면 그건 더 이상 예외가 아닙니다.

    예를 들어 파라미터에 대한 검증을 잘 했다고 하면, 그것으로 인해서 예외가 발생하지 않을 것이고 그럼 NullPointException이라든가 NumberFormatException 같은 것이 일어날 가능성이 줄어들거나 없어지겠죠.

    프로그래머의 실력에 따라서 생각할 수 있는 예외의 숫자도 다르겠지만, 적절한 처리에 의해서 발생할 예외도 적어질 겁니다.


    2. 예외의 가능성과 빈도를 분리해보셔야 할 것 같습니다.

    DB에서 데이터를 가져오지 못하는 이유는 무엇일까요? SQL문이 잘못되었을 수도 있고, 네트워크 통신 문제일수도 있고...

    어떤 건 그냥 에러 찍고 넘어가면 괜찮지만, 어떤 건 오히려 시스템을 종료하는게 나을 수도 있죠.

    귀찮은 것 말고는 가급적 예외를 분리해서 처리하는 것이 좋습니다.


    3. 이것은 말로 간단히 설명하기는 어렵겠네요.

    코드 추상화 레벨을 잘 관리하시면, 말씀하신 상황 자체가 이상하다는 것을 알 수 있습니다.

    Controller, Service, Dao 같은 레이어를 나누는 이유가 무엇일지 생각해보세요.


    자기가 처리할 수 있는 예외는 자기가 처리하는게 맞고, 자기자 처리할 수 없으면 호출한 쪽으로 넘기는게 맞습니다.

    컨트롤러에서 update, select 를 직접 호출하지 않고 다른 메소드로 분리를 하시고,

    그쪽에서 직접 처리할 예외는 직접 처리하게 하세요.


    글쓴분께서 어떤 상황을 서술하시는 내용으로 볼 때에는 아직 코드 작성 경험이 많지 않으신 것 같네요.

    그 정도 수준에서는 게시판에서 질문을 해서 답을 구하기 보다는 책을 보고 공부하시는 것이 좋을 것 같습니다.

    바로 떠오르는 책은 '코드 컴플리트'나 '리팩터링'인데, 이런 의문을 가지신 분이 그 책을 보시면 도움이 굉장히 많이 될 겁니다.

  • 무명소졸
    6k
    2022-07-06 12:46:53

    적절한 예외 처리에 완벽한 정답은 없는 것 같습니다.

    사실 개발자가 그런 부분을 도메인에 알맞게 잘 설계하는 것이 중요한 능력중 하나인 것 같네요

    아래와 같은 코드에 어떤게 더 낫다고 할 수 있을까요??


    int getLenghOfInputStr(String inputStr) {
     if (inputStr == null) {
       throw new EmptyParamerter();
     }
    }
    
    
    int getLengthOfInputStr(String inputStr) {
    if (inputStr == null) {
     return -1;
    }


  • kenu
    63k
    2022-07-06 15:09:50
    해당 게시물은 관리자에 의해 사는얘기에서 Tech Q&A로 이동 되었습니다.
  • ansdbduf
    940
    2022-07-06 23:53:25 작성 2022-07-07 00:37:07 수정됨

    Http 응답코드에 따라 예외처리

    400번에러 : 너가 입력한 값에 문제가 있어. 클라이언트에게 책임 회피(예 : 필수항목인데 null값줄때) throw new BadRequestException("name", "not null", "이름내놔")

    401번에러: 로그인이 필요한 기능인데 안했네? throw new UnauthorizedException("댓글을 작성할려면 로그인이 필요해")

    403번 에러: 너는 이 데이터에 접근할수 없어 throw new ForbiddenException("당신은 이 게시글을 삭제할수 있는 권한이 없어요.")

    404번 에러 : 너가 조회할 데이터를 db에서 찾아보니 없더라 throw new ResourceNotFoundExcepton("게시글이 삭제되었거나 존재하지 않아요")

    500번 에러 : 아 서버단오류다 ㅠㅠ. 문제점(주로 sql쿼리)을 찾아 수정하거나 400번대 오류로 둔갑.


    예외는 400번대만 생성하여 던지고 500번대는 try catch로 잡지않고 최종말단(exceptionhandler)에서 로그 남기고 그 문제점을 수정

    400번은 FormValidation 라이브러리로 공통처리 +로직내에 업무적인 예외

    401/403번은 Filter에서 주로 처리

    404는 로직내에서 처리

  • 로그인을 하시면 답변을 등록할 수 있습니다.