[Spring] ์ข‹์€ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋Š” ๋ฌด์—‡์ผ๊นŒ์— ๋Œ€ํ•œ ๊ถ๊ธˆ์ฆ

728x90

 

 


 

๐Ÿ“Œ Java & SpringBoot & JPA ํ™˜๊ฒฝ์—์„œ ๊ฐœ๋ฐœ์ค‘์ž„.

 

 

์„œ๋ก 


Java/SpringBoot ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค๋ฌด๋ฅผ ํ•˜๊ณ ์žˆ๋‹ค.

๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผํ• ์ผ์ด ์ƒ๋‹นํžˆ ๋งŽ์ด ์ƒ๊ธธ ๊ฒƒ์ด๋‹ค

๋Œ€ํ‘œ์ ์œผ๋กœ Java ํ•˜๋ฉด NullPointException ์ด ์žˆ์„ ๊ฒƒ์ด๋‹ค

์ ์ ˆํ•œ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š๊ณ , Runtime ์—๋Ÿฌ๊ฐ€ ์ƒ๊ธธ ๊ฒฝ์šฐ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์žฅ์• ๊ฐ€ ์ƒ๊ธธ ๊ฒƒ์ด๋‹ค

์‹ฌํ•˜๋ฉด ์„œ๋น„์Šค๊ฐ€ ์ค‘๋‹จ์ด ๋˜๋Š” ์ƒํ™ฉ๋„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค

๊ทธ๋งŒํผ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋Š” ๊ท€์ฐฎ์ง€๋งŒ ์ค‘์š”ํ•œ ์ผ์ด๋‹ค. ์†Œํ™€ํžˆ ํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค

์œ„ ์ƒํ™ฉ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ์ ์ ˆํ•œ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๊ฐ€ ํ•ญ์ƒ ํ•„์š”ํ•˜๋‹ค

์•„๋ž˜ ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉฐ ํ•œ๋ฒˆ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ์ ์ง„์ ์œผ๋กœ ๋ฐœ์ „์‹œ์ผœ๋ณด์ž.

์˜ˆ์‹œ๋Š” DB ์™€ ํ†ต์‹ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ์˜ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ์ด๋‹ค

์ผ๋‹จ try ~ catch ์— ๋Œ€ํ•œ ๋ฐฉ๋ฒ•์€ ์ด์•ผ๊ธฐ ํ•˜์ง€ ์•Š์œผ๋ ค๊ณ  ํ•œ๋‹ค

๋ฌผ๋ก  ์‚ฌ์šฉํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ ์Šคํ”„๋ง์—๋Š” @Transactional ์ด๋ผ๋Š” ์•„์ฃผ ์ข‹์€ ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค

๊ทธ๋ฆฌ๊ณ  try~catch ๋Š” ์˜ˆ์™ธ๋ฅผ ์žก์€ ํ›„์— ํ›„์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ๋œ๋‹ค. ํ•˜์ง€๋งŒ DB ์กฐํšŒ์™€ ๊ด€๋ จ๋œ ์ƒํ™ฉ์—์„œ ํ›„์ฒ˜๋ฆฌ๋Š” ๋ถˆํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค
ex) I/O ์ž‘์—…์—์„œ ๋Œ€๋ถ€๋ถ„ ์‚ฌ์šฉํ•จ.

 

 

๋ณธ๋ก 


@Getter
@Entity
public class Member {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private String memberId;

    private String password;

    @OneToMany(mappedBy = "member", cascade = { CascadeType.PERSIST, CascadeType.REMOVE}, orphanRemoval = true)
    private List<Product> products = new ArrayList<>();
}

@Getter
@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private Integer price;
    private Integer quantity;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_id", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
    private Member member;

}

 

๊ธฐ๋ณธ์ ์œผ๋กœ ์œ„ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์กด์žฌํ•œ๋‹ค. ์ด์— ๋”ฐ๋ฅธ Repository ๋˜ํ•œ ์ž‘์„ฑ์ด ๋˜์–ด ์žˆ๋‹ค

 

 

1. id ๋ฅผ ํ†ตํ•˜์—ฌ ์กฐํšŒํ•˜๋Š” ์ƒํ™ฉ

์•„๋ฌด๊ฒƒ๋„ ๋ชจ๋ฅด๊ณ  ๋ง‰ ๊ฐœ๋ฐœํ•  ๋•Œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ณ ๋Š” ํ–ˆ๋‹ค.

 

1-1) RuntimeException ์‚ฌ์šฉํ•œ ์˜ˆ์™ธ์ฒ˜๋ฆฌ

@RequiredArgsConstructor
@Service
public class MemberService {

    private final MemberRepository memberRepository;

    public Member findMember(Long id) {
        Member member = memberRepository.findById(id)
            .orElseThrow(() -> new RuntimeException("Member is Null"));

        return member;
    }
}

 

์ œ์ผ ๋งŒ๋งŒํ•˜๋ฉด์„œ ์‰ฌ์šด ๋ฐฉ๋ฒ•์ค‘ ํ•˜๋‚˜์ด๋‹ค

๊ทธ๋ฆฌ๊ณ  ์œ„ ์ฝ”๋“œ๋ฅผ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์‹คํ–‰์‹œ์ผœ ๋ณด๊ฒ ๋‹ค.

@SpringBootTest(classes = DddStartApplication.class)
class MemberServiceTest {

    @Autowired
    private MemberService memberService;

    @Test
    @DisplayName("Member ๋ฅผ ์กฐํšŒํ•œ๋‹ค.")
    void findMemberTest() {
        // given
        Long id = 2839823L;

        // when
        Member member = memberService.findMember(id);

        // then
        Assertions.assertThat(member).isNotNull();
    }

}

 

์•„๋ž˜ ์‚ฌ์ง„๊ณผ ๊ฐ™์€ ๋กœ๊ทธ๊ฐ€ ๋‚˜์˜จ๋‹ค

์‚ฌ์‹ค ๋งจ์ฒ˜์Œ์—๋Š” ์œ„ ์—๋Ÿฌ์ฒ˜๋ฆฌ ๋˜ํ•œ ๋‚˜์˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค

ํ•˜์ง€๋งŒ ๋ถ„๋ช…ํžˆ ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์žˆ์„ ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๊ณ , ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.


1-2) CustomException ์‚ฌ์šฉํ•œ ์˜ˆ์™ธ์ฒ˜๋ฆฌ + ๋‚ด์šฉ ์ถ”๊ฐ€

์ข€๋” ๋ช…์‹œ์ ์œผ๋กœ ์—๋Ÿฌ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , ์—๋Ÿฌ ๊ด€๋ จ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•ด๋ณด๊ฒ ๋‹ค.

public class MemberException extends RuntimeException{

    public MemberException () {
    }

    public MemberException (String message) {
        super(message);
    }

    public MemberException (String message, Throwable cause) {
        super(message, cause);
    }

    public MemberException (Throwable cause) {
        super(cause);
    }

    public MemberException (String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }

}

 

Member ์™€ ๊ด€๋ จ๋œ Exception ์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด MemberException ์„ ๋งŒ๋“ค๊ณ  RuntimeException ์„ ์ƒ์†๋ฐ›์•˜๋‹ค

RuntimeException ์€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰์‹œ ์ฒดํฌํ•˜์ง€ ์•Š๋Š” ์˜ˆ์™ธ(=UnCheckedException) ์ด๋ฏ€๋กœ, ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‚ฌ์šฉ์ค‘์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

 

๊ทธ๋ฆฌ๊ณ  RuntimeException ์ƒ์„ฑ์ž๋ฅผ ๋ชจ๋‘ ๊ตฌํ˜„๋ฐ›๋Š”๋‹ค

    public Member findMember(Long id) {
        Member member = memberRepository.findById(id)
            .orElseThrow(() -> new MemberException(id + "์— ํ•ด๋‹นํ•˜๋Š” ํšŒ์›์ด ์กด์žฌ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."));

        return member;
    }
    @Test
    @DisplayName("Member ๋ฅผ ์กฐํšŒํ•œ๋‹ค.")
    void findMemberTest() {
        // given
        Long id = 2839823L;

        // when
         memberService.findMember(id);

        // then
        //Assertions.assertThat(member).isNotNull();
    }

 

๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค

 

 

์œ„ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฆฌ๋ˆ…์Šค ํ…Œ์ŠคํŠธ,์šด์˜ ํ™˜๊ฒฝ์— ์˜ฌ๋ ธ์„ ๋•Œ ์—๋Ÿฌ ๋ฐœ์ƒ์‹œ ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ๋กœ๊ทธ๋กœ ์ฐํžˆ๊ฒŒ ๋œ๋‹ค

org.hyeonqz.dddstart.exception.MemberException: 2839823์— ํ•ด๋‹นํ•˜๋Š” ํšŒ์›์ด ์กด์žฌ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    at org.hyeonqz.dddstart.application.MemberService.lambda$findMember$0(MemberService.java:18)
    at java.base/java.util.Optional.orElseThrow(Optional.java:403)
    at org.hyeonqz.dddstart.application.MemberService.findMember(MemberService.java:18)
    at org.hyeonqz.dddstart.application.MemberServiceTest.findMemberTest(MemberServiceTest.java:27)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

 

์œ„ ์—๋Ÿฌ ๋กœ๊ทธ๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ ๋‚˜์˜ค๋Š” ์—๋Ÿฌ ๋กœ๊ทธ๋ผ ๋งจ์œ„์— ์—๋Ÿฌ ๊ด€๋ จ ๋‚ด์šฉ์ด 1์ค„ ๋” ์ถ”๊ฐ€๋˜์–ด ์žˆ๋‹ค. ๋ฌด์‹œํ•ด๋„ ๋œ๋‹ค

 

1-3) CustomException + ErrorCode ์‚ฌ์šฉ

์œ„์— ๋ฐฉ๋ฒ•๋„ 1๋ฒˆ ๋ฐฉ๋ฒ•๋ณด๋‹ค๋Š” ๊ทธ๋ž˜๋„ ๋‚ซ๋‹ค. Exception ์ด๋ฆ„๋„ ๋ช…์‹œ์ ์œผ๋กœ ๋ฐ”๋€Œ์—ˆ๊ณ , ์—๋Ÿฌ ๋‚ด์šฉ ๋˜ํ•œ ์ถ”๊ฐ€๋˜์–ด ๋กœ๊ทธ๋ฅผ ๋ณด๊ธฐ ๋” ์‰ฌ์›Œ์กŒ๋‹ค

์—ฌ๊ธฐ์„œ ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์žˆ์„๊นŒ?

์—ฌ๋Ÿฌ ๊ณ ๋ฏผ ๋์— ์ƒ๊ฐ๋‚œ ๋‹ค์Œ ๋ฐฉ๋ฒ•์€ ์—๋Ÿฌ ์ƒํ™ฉ์„ ์ƒ๊ฐํ•ด๋ณด๊ณ  ์—๋Ÿฌ ์ฝ”๋“œ๋ฅผ ์ •์˜ํ•ด๋‘๊ณ  ์‚ฌ์šฉํ•˜์ž์˜€๋‹ค

๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด id ๋งŒ ์กฐํšŒํ•˜์ง€ ์•Š๊ณ  ์—ฌ๋Ÿฌ ์—๋Ÿฌ ์ƒํ™ฉ์ด ๋ถ„๋ช… ์ƒ๊ธด๋‹ค

์ด์— ๋”ฐ๋ฅธ ErrorCode ๋ฅผ ์ •์˜ํ•ด๋‘๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

public interface ErrorCode {
    String getCode();

    String getDescription();

    default String getMessage() {
        return String.format("[%s] %s", getCode(), getDescription());
    }
}
@RequiredArgsConstructor
public enum MemberErrorCode implements ErrorCode {
    UNKNOWN_MEMBER_ID(INTERNAL_SERVER_ERROR,"ID ์— ํ•ด๋‹นํ•˜๋Š” ํšŒ์›์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."),
    BAD_CREDENTIALS(UNAUTHORIZED, "๊ณ„์ • ์ •๋ณด๊ฐ€ ์ž˜๋ชป๋˜์—ˆ์Šต๋‹ˆ๋‹ค."),
    ;

    private final HttpStatus httpStatus;
    private final String description;

    @Override
    public String getCode () {
        return this.name();
    }
}
public class MemberException extends RuntimeException{

    private ErrorCode errorCode;
    private Errors errors;
    private Throwable errorCause;

    public MemberException(ErrorCode errorCode) {
        super(errorCode.getMessage());

        this.errorCode = errorCode;
    }

    public MemberException(ErrorCode errorCode, Errors errors) {
        super(errorCode.getMessage());

        this.errorCode = errorCode;
        this.errors = errors;
    }

    public MemberException(ErrorCode errorCode, Throwable errorCause) {
        super(errorCode.getMessage(), errorCause);

        this.errorCode = errorCode;
        this.errorCause = errorCause;
    }

    public MemberException(ErrorCode errorCode, Errors errors, Throwable errorCause) {
        super(errorCode.getMessage(), errorCause);

        this.errorCode = errorCode;
        this.errors = errors;
        this.errorCause = errorCause;
    }

    public MemberException(ErrorCode errorCode, String message) {
        super(String.format("%s (Value: %s)", errorCode.getMessage(), message));
        this.errorCode = errorCode;
    }
}
    public Member findMember(Long id) {
        Member member = memberRepository.findById(id)
            .orElseThrow(() -> new MemberException(MemberErrorCode.UNKNOWN_MEMBER_ID));

        return member;
    }

 

๊ณผ์—ฐ ๊ฒฐ๊ณผ๋Š” ์–ด๋–ป๊ฒŒ ๋ฐ”๋€Œ์—ˆ์„๊นŒ?

 

๋ฏธ๋ฆฌ ์ •์˜ํ•ด๋‘” ErrorCode ๋Œ€๋กœ ์—๋Ÿฌ ๋กœ๊ทธ๊ฐ€ ๋‚˜์™”๋‹ค. ์ข€ ๋” ๋””ํ…Œ์ผํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด httpStatus ์ฝ”๋“œ๋„ ์ถ”๊ฐ€ํ•˜๊ณ  ๋งˆ์Œ๋Œ€๋กœ Custom ํ•  ์ˆ˜๋„์žˆ๋‹ค



๋ฏธ๋ฆฌ enum ์ •์˜๋ฅผ ํ•ด๋‘ ์œผ๋กœ์จ ์ข€ ๋” ์œ ๋™์ ์œผ๋กœ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค

์ฒ˜์Œ๋ณด๋‹ค ํ›จ์”ฌ ๋‚ซ๋‹ค. ํ•˜์ง€๋งŒ ๋ญ”๊ฐ€ ์‚ด์ง ์•„์‰ฝ๋‹ค. ์šด์˜ ์ƒํ™ฉ์—์„œ ์ €๊ฒƒ๋ณด๋‹ค ๊ธด ์—๋Ÿฌ ๋กœ๊ทธ๋“ค์€ ํ›จ์”ฌ ๋งŽ์ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค

๊ทธ๋ž˜์„œ ๊ณ ๋ฏผ๋˜๋Š” ํฌ์ธํŠธ๊ฐ€ ํ•œ๊ฐœ ์žˆ๋‹ค

 

ํ˜„์žฌ๋Š” ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ธด ํ•˜์ง€๋งŒ, ๊ฒฐ๊ตญ์€ printStackTrace ์— ์˜ํ•ด ๊ธด ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ์ถœ๋ ฅ์ด ๋œ๋‹ค

printStackTrace ์ฒ˜๋Ÿผ ์—๋Ÿฌ ๋กœ๊ทธ๋ฅผ ์ญˆ์šฑ ๋ณด์—ฌ์ฃผ๋Š”๊ฒŒ ๊ณผ์—ฐ ์ข‹์€๊ฑธ๊นŒ? ๊ณผ์—ฐ ๋ฌธ์ œ๋ฅผ ๋น ๋ฅด๊ฒŒ ํ•ด๊ฒฐํ•˜๊ธฐ์— ์ข‹์„๊นŒ?

์•„๋‹ˆ๋ฉด ์—๋Ÿฌ ๋กœ๊ทธ๋ฅผ ์งง๊ฒŒ ๋ณด์—ฌ์ฃผ๋ฉด ๋กœ๊ทธ๋Š” ์งง๊ฒŒ ๋ณด์ด์ง€๋งŒ ๋‚ด๊ฐ€ ๋ฐ”๋กœ ์žฅ์•  ์œ„์น˜ ๋ฐ ํ•ด๊ฒฐ์„ ๋น ๋ฅด๊ฒŒ ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

์œ„ ๋ถ€๋ถ„์—์„œ ํ•ญ์ƒ ๋”œ๋ ˆ๋งˆ์— ๋น ์ง€๊ณ  ๊ณ ๋ฏผ์„ ํ•˜๊ฒŒ ๋œ๋‹ค

ํ˜„์žฌ ์‹ค๋ฌด์—์„œ๋Š” printStackTrace() ๋ž‘ log.error ๋ฅผ ํ†ต์šฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ธฐ๋Š” ํ•˜๋‹ค

๊ทธ๋ฆฌ๊ณ  logback-spring.xml ์„ ์ •์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ธฐ์— ํŒ€ ๋ฃฐ ์—๋”ฐ๋ผ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ด ๋‹ค๋ฅผ ๊ฒƒ์ด๋‹ค

๋‹ค์Œ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” printStackTrace() ๊ฐ€ ์•„๋‹Œ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ์—๋Ÿฌ๊ฐ’๋งŒ ๋”ฑ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž



1-4) ๋กœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•œ ์งง์€ ์—๋Ÿฌ์ฒ˜๋ฆฌ + GlobalExceptionHandler

๋ณดํ†ต ์œ„ ๋ฐฉ์‹์€, ์šด์˜ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…” ๋กœ๊ทธ์— ์ฐํžˆ๋Š”๊ฑธ ๋ชฉ์ ์œผ๋กœ ํ•˜๊ธฐ ๋ณด๋‹ค๋Š”, ํด๋ผ์ด์–ธํŠธ์— ์–ด๋– ํ•œ ์‘๋‹ต์„ ์ค„ ๋•Œ๋Š” printStackTrace ๋Š” ํ•„์š”์—†๊ธฐ์— ํ•œ์ค„ ์‘๋‹ต์„ ์ฃผ๊ธฐ ์œ„ํ•ด ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค.

 


์„œ๋น„์Šค์—์„œ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ณ  GlobalException ์œผ๋กœ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•œ๋‹ค.

    public Member findMember(Long id) {
        Member member = memberRepository.findById(id)
            .orElseThrow(() -> new MemberException(MemberErrorCode.UNKNOWN_MEMBER_ID));

        return member;
    }
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(MemberException.class)
    public ResponseEntity<String> handleMemberException(MemberException ex) {
        log.error("์˜ˆ์™ธ ๋ฐœ์ƒ: {}", ex.getMessage());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST)
            .body(ex.getMessage());
    }
}

 

 

[UNKNOWN_MEMBER_ID] ID ์— ํ•ด๋‹นํ•˜๋Š” ํšŒ์›์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (Value: 2839823)

 

์—๋Ÿฌ ๋ฐœ์ƒ์‹œ ์œ„์ฒ˜๋Ÿผ 1์ค„ ๋กœ๊ทธ๋ฅผ ๋ฝ‘์•„๋‚ผ ์ˆ˜ ์žˆ๋‹ค

 

๊ฒฐ๋ก 

์˜ˆ์™ธ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์€ ๋ฌด์ˆ˜ํžˆ๋„ ๋งŽ๋‹ค

๊ทธ๋ฆฌ๊ณ  ํŒ€๋งˆ๋‹ค ๋ถ„๋ช… ๋‹ค๋ฅผ ๊ฒƒ์ด๋‹ค

๊ทธ๋Ÿฌ๋ฏ€๋กœ ๋‚˜๋Š” ๋‚˜๋งŒ์˜ ์›์น™์„ ์ง€ํ‚ค๊ณ , ํŒ€ ๊ทœ์œจ์„ ๋”ฐ๋ฅผ ์ˆ˜ ์žˆ๋„๋ก ํ•ด์•ผํ•  ๊ฒƒ์ด๋‹ค

 

์ข€ ๋” ์ข‹์€ ์—๋Ÿฌ์ฒ˜๋ฆฌ๋ฅผ ์ƒ๊ฐํ•ด๋ณด๋ฉด ๊ฐ„๋‹จํ•œ ์—๋Ÿฌ์ผ ๊ฒฝ์šฐ ๋กœ๊ทธ๋กœ ์ฐ์–ด์„œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„ ๋กœ๊ทธ์— ๋ณด๊ด€ํ•˜๊ณ 
์ •๋ณด๊ฐ€ ๋งŽ์ด ํ•„์š”ํ•œ ์—๋Ÿฌ ์ผ ๊ฒฝ์šฐ ๋กœ๊ทธ๋ฅผ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ •๋ง ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค

 

๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” ELK,Kibana ๋“ฑ ๋กœ๊ทธ ๋ชจ๋‹ˆํ„ฐ๋ง์ด ๋˜๋ฉด ์ข‹์„ ๊ฒƒ์ด๋‹ค

ํ•˜์ง€๋งŒ ํ˜„์žฌ ์‹ค๋ฌด๋Š” ๊ทธ๋ ‡์ง€ ์•Š์œผ๋‹ˆ ๋ญ ๋‚˜์ค‘์— ๋‚ด๊ฐ€ ๊ตฌ์ถ•์„ ํ•ด๋ณด๋“ ๊ฐ€ ํ•ด์•ผ๊ฒ ๋‹ค

 

 

๐Ÿ“Œ ์˜ˆ์™ธ์ฒ˜๋ฆฌ์—์„œ ๋‚˜๋งŒ์˜ ์›์น™

  1. ์˜ˆ์™ธ์—๋Š” ์ตœ๋Œ€ํ•œ ๋งŽ์€ ์ •๋ณด๋ฅผ ๋„ฃ์ž.
  2. e.printStackTrace ๋Š” ํ•„์š”์— ์˜ํ•ด์„œ ์‚ฌ์šฉํ•˜๋˜ ์ตœ๋Œ€ํ•œ ์ง€์–‘ํ•˜์ž...
  3. ๊ฒฐ๊ตญ ํ…Œ์ŠคํŠธ, ์šด์˜์—์„œ ๋กœ๊ทธ๋ฅผ ๋ณด๋ฉฐ ์žฅ์• ๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋กœ๊ทธ๋งŒ ๋ดค์„ ๋•Œ ๋ฌธ์ œ๋ฅผ ์œ ์ถ”ํ•˜๊ณ  ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ์ ์ ˆํ•˜๊ณ  ๋งŽ์€ ์ •๋ณด๋ฅผ ๋„ฃ์ž๊ฐ€ ๋ชจํ† ์ด๋‹ค.

 

 

Code GitHub : https://github.com/Hyeonqz/HyeonKyu-Lab/tree/master/spring-lab/src/main/java/org/hyeonqz/springlab/exceptionEx

 

HyeonKyu-Lab/spring-lab/src/main/java/org/hyeonqz/springlab/exceptionEx at master · Hyeonqz/HyeonKyu-Lab

ํ‰์†Œ ๊ถ๊ธˆํ–ˆ๋˜ ๋‚ด์šฉ์„ ์‹คํ—˜ํ•ด๋ณด๋Š” ์—ฐ๊ตฌ์†Œ(Java). Contribute to Hyeonqz/HyeonKyu-Lab development by creating an account on GitHub.

github.com

 

 

 

728x90