Exception Handling

์˜ˆ์™ธ๋Š” ์–ด๋””์„œ ์žก๊ณ , ์–ด๋–ป๊ฒŒ ๋˜์ ธ์•ผ ํ• ๊นŒ์š”?

์žฌ์‹œ๋„์™€ ํƒ€์ž„์•„์›ƒ ๊ตฌํ˜„์„ ๋‹ค๋ฃจ๋ฉด์„œ ์˜ˆ์™ธ๋ฅผ ์™ธ๋ถ€ API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์žก์•„์„œ ๋˜์ ธ์•ผ ํ• ์ง€, ์•„๋‹ˆ๋ฉด ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ• ์ง€์™€ ๊ฐ™์€ ๊ณ ๋ฏผ์„ ํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋ฉ”์ผ ์˜ˆ์ œ์—์„œ๋Š” SMTP Clinet๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ์žฌ์‹œ๋„

  • ๊ฒฐ์ œ ์˜ˆ์ œ์—์„œ๋Š” PG๋ฅผ ํ˜ธ์ถœํ•˜๋Š” PG Client์—์„œ ์˜ˆ์™ธ๋ฅผ ํ•ธ๋“ค๋งํ•˜์—ฌ ์žฌ์‹œ๋„

์ด๋Ÿฐ ์ฐจ์ด๋Š” ์ ์ ˆํ•œ ๊ธฐ์ค€์„ ๊ฐ€์ง€๊ณ  ์ ์ ˆํ•œ ์œ„์น˜์— ์ ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์™ธ ํ•ธ๋“ค๋ง ์œ„์น˜๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๊ธฐ์ค€

1. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์˜์กด์„ฑ ๊ฒฉ๋ฆฌ

์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(RestTemplate, WebClient, SMTP Client ๋“ฑ)๋Š” ๊ฐ์ž ๊ณ ์œ ํ•œ ์˜ˆ์™ธ(ReadTimeoutException, RestClientException ๋“ฑ)๋ฅผ ๋˜์ง‘๋‹ˆ๋‹ค.

[๋‚˜์œ ์˜ˆ] ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์˜ˆ์™ธ๋ฅผ ์„œ๋น„์Šค๋‚˜ ์ปจํŠธ๋กค๋Ÿฌ๊นŒ์ง€ ๊ทธ๋Œ€๋กœ ํ˜๋ ค๋ณด๋‚ด๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.

// Service Layer
try {
    // WebClient ์‚ฌ์šฉ ์ค‘ ๋ฐœ์ƒํ•œ Netty ์ „์šฉ ์˜ˆ์™ธ
} catch (io.netty.handler.timeout.ReadTimeoutException e) { 
    // ...
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์„œ๋น„์Šค ์ฝ”๋“œ๊ฐ€ ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(Netty)์— ๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋ฉ๋‹ˆ๋‹ค.

๋‚˜์ค‘์— HTTP ํด๋ผ์ด์–ธํŠธ๋ฅผ OpenFeign์ด๋‚˜ RestTemplate์œผ๋กœ ๋ฐ”๊พธ๋ฉด, ์„œ๋น„์Šค ์ฝ”๋“œ์˜ catch ๋ธ”๋ก์„ ์ „๋ถ€ ๋‹ค ๊ณ ์ณ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

[์ข‹์€ ์˜ˆ] ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ(Client/Adapter) ๊ณ„์ธต์—์„œ ์˜ˆ์™ธ๋ฅผ ์žก๊ณ , ์šฐ๋ฆฌ ์‹œ์Šคํ…œ์˜ ์ปค์Šคํ…€ ์˜ˆ์™ธ๋กœ ๋ฐ”๊ฟ”์„œ ๋˜์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์„œ๋น„์Šค ๊ณ„์ธต์€ ๊ตฌ์ฒด์ ์ธ ํ†ต์‹  ๊ธฐ์ˆ ์„ ๋ชฐ๋ผ๋„ ๋˜๊ณ , PaymentGatewayTimeoutException๋งŒ ์ฒ˜๋ฆฌํ•˜๋ฉด ๋˜๋ฏ€๋กœ ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ํฌ๊ฒŒ ํ–ฅ์ƒ(DIP ์ค€์ˆ˜)๋ฉ๋‹ˆ๋‹ค.

2. ์žฌ์‹œ๋„ ๋ฒ”์œ„ ์ตœ์†Œํ™”

@Retryable์„ ์–ด๋””์— ๋ถ™์ด๋А๋ƒ์— ๋”ฐ๋ผ ์žฌ์‹œ๋„๋˜๋Š” ์ฝ”๋“œ์˜ ๋ฒ”์œ„๊ฐ€ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

๋ฉ”์ผ ์ „์†ก ์„œ๋น„์Šค์— ์ด๋ฉ”์ผ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ(Validation) ๋กœ์ง๊ณผ SMTP ์ „์†ก ๋กœ์ง์ด ์„ž์—ฌ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

[์„œ๋น„์Šค ์ „์ฒด์— ์žฌ์‹œ๋„ ์ ์šฉ ์‹œ ๋ฌธ์ œ์ ]

๋งŒ์•ฝ smtpClient.send()์—์„œ ์‹คํŒจํ•˜๋ฉด, validate(email)๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

๋ฌผ๋ก  ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋Š” ๊ฐ€๋ณ์ง€๋งŒ, ๋งŒ์•ฝ ๋ฌด๊ฑฐ์šด DB ์ž‘์—…์ด๋‚˜ ์ค‘๋ณต๋˜๋ฉด ์•ˆ ๋˜๋Š” ๋กœ์ง์ด ์„ž์—ฌ ์žˆ๋‹ค๋ฉด ๋ฌธ์ œ๊ฐ€ ์ปค์ง‘๋‹ˆ๋‹ค.

[ํ•ด๊ฒฐ์ฑ…: ์ฑ…์ž„ ๋ถ„๋ฆฌ] ์žฌ์‹œ๋„๊ฐ€ ํ•„์š”ํ•œ ์™ธ๋ถ€ ํ†ต์‹  ๋กœ์ง๋งŒ ๋ณ„๋„ ํด๋ž˜์Šค๋กœ ๋ถ„๋ฆฌํ•˜๊ณ , ๊ทธ๊ณณ์— ์žฌ์‹œ๋„๋ฅผ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.

์•ž์—์„œ ๊ฒฐ์ œ ์˜ˆ์‹œ์™€ ์œ ์‚ฌํ•œ ์ฝ”๋“œ๋กœ ๊ตฌ์„ฑ๋˜๋ฉด์„œ, ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์žฌ์‹œ๋„ ๋‹จ์œ„๋ฅผ ์ข๊ฒŒ ์ œํ•œํ•˜์—ฌ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์š”์•ฝ: ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ธฐ์ค€

  1. ์–ด๋””์„œ ์žก์„๊นŒ? (Catch)

    • ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ€์žฅ ์ตœ์ „์„ (Client/Adapter Class)์—์„œ ์žก๋Š”๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

  2. ๋ฌด์—‡์„ ๋˜์งˆ๊นŒ? (Throw)

    • ๊ธฐ์ˆ  ์ข…์†์ ์ธ ์˜ˆ์™ธ(NettyException ๋“ฑ)๋ฅผ ๊ทธ๋Œ€๋กœ ๋˜์ง€์ง€ ๋ง๊ณ , ๋น„์ฆˆ๋‹ˆ์Šค ์˜๋ฏธ๋ฅผ ๋‹ด์€ ์ปค์Šคํ…€ ์˜ˆ์™ธ(PaymentException ๋“ฑ)๋กœ ํฌ์žฅ(Wrap)ํ•ด์„œ ๋˜์ง€๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

  3. ์–ด๋””๋ฅผ ์žฌ์‹œ๋„ํ• ๊นŒ? (Retry)

    • ์„œ๋น„์Šค ์ „์ฒด๋ฅผ ์žฌ์‹œ๋„ํ•˜์ง€ ๋ง๊ณ , ์‹คํŒจ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์€ ์™ธ๋ถ€ ํ†ต์‹  ๊ตฌ๊ฐ„๋งŒ ๋ณ„๋„ ํด๋ž˜์Šค๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ์žฌ์‹œ๋„๋ฅผ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ธฐ์ค€์€ ๋‹จ์ˆœํžˆ ์—๋Ÿฌ๋ฅผ ๋ง‰๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์ข‹์€ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“œ๋Š” ํ•ต์‹ฌ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ถ”์ƒํ™”: ๊ตฌํ˜„ ๊ธฐ์ˆ ์ด ๋ฐ”๋€Œ์–ด๋„ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๊ณ  ๋ณดํ˜ธ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊ฒฉ๋ฆฌ: ์žฌ์‹œ๋„๋Š” ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์ˆ˜ํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Last updated