반응형
LinkedIn 개발자로 성장하면서 남긴 발자취들을 확인하실 수 있습니다.
Github WWDC Student Challenge 및 Cherish, Tiramisul 등 개발한 앱들의 코드를 확인하실 수 있습니다.
개인 앱 : Cherish 내 마음을 들여다보는 시간, 체리시는 디자이너와 PM과 함께 진행 중인 1인 개발 프로젝트입니다.
10년 후, 20년 후 나는 어떤 스토리 텔러가 되어 있을지 궁금하다. 내가 만약에 아직 조금 더 탐구하고 싶은 게 있고, 궁금한 게 있다면, 그게 설사 지금 당장의 내 인생에 도움이 안 되는 것 같더라도 경험해보자. 그 경험들을 온전히 즐기며 내 것으로 만들고, 내 일에 녹여내고... 그러다보면 그 점들이 모여 나란 사람을 그려내는 선이 될 테니까.

Recent Posts
Recent Comments
Total
관리 메뉴

꿈꾸는리버리

[Swift Concurrency 1] 에러처리 try-catch문 / Result 본문

오뚝이 개발자/SwiftUI

[Swift Concurrency 1] 에러처리 try-catch문 / Result

rriver2 2024. 2. 2. 02:41
반응형

Cherish 백업 기능을 구현하면서 다시 공부하게 된 Swift Concurrency.... 

오늘부터 Swift Concurrency 시리즈를 올릴려고 한다. 

그리고 그 시작으로 오늘은 Swift Concurrency 1) 에러처리에 대한 이야기로, try-catch문과 Result에 대한 내용이다!


 try-catch문/ Result를 사용해야 할까? 

1️⃣ 예시 코드

위 코드를 확인해보자. View에서는 Viewmodel을, Viewmodel에서는 manager를 가지고 있다.

ViewModel의 fetchTitle 함수를 통해 title 값을 변경한다.

이때 Manager의 fetchTitle에서는 isActive 값을 통해서 "New Text!"를 반환할지, nil을 반환할지 결정하게 된다. 

그래서 ViewModel에서는 newTitle이 nil값인지 확인을 해서 nil값이 아니라면 text의 값을 newTitle로 변환한다.

💡질문
Manager가 네트워킹을 처리하는 부분이라고 할 때,
처음 이 코드를 보는 사람은 ViewModel의 fetchTitle을 보고 "newTitle 값에 nil이 들어간 경우 네트워킹이 실패한 경우, 값이 있는 경우 네트워킹이 해결된 경우"라고 생각할 수 있을까....?


-> 물론 이렇게 해석할 수도 있겠지만, 만약 실패한 경우를 300, 400, 404 등 여러가지로 처리를 해야 한다면? 실패한 경우의 메세지를 출력해야 한다면? 코드가 많이 지저분해질 것이다.

 

2️⃣ 에러 케이스처리

1에서 [💡질문 ]에서 했던 질문을 해결할 수 있는 코드를 작성했다.

만약 isActive가 true라면, [title에 "NEW TEXT!"를, error에는 nil], 아니라면 [title에는 nil을,각 케이스에 맞게 error]를 반환한다.

💡질문
title과 error를 모두 필요로 하는 경우가 있을까? 이를 튜플로 묶을 이유가 있을까? 

-> 만약 isActive가 true라면, title에 "NEW TEXT!"만, 아니라면 각 케이스에 맞게 error만을 반환할 수 없을까?

 

그래서 필요한 것이 Result<Success, Failure>와 Try-catch문이다.

try-catch 문이 나오고 나서 좀 더 깔끔한 코드를 작성하기 위해 Result가 나왔고 이에 대한 방법은 swift 공식 문서에 나와 있다. 

💡 질문
[try-catch]가 존재하는데 [Result<success, failure>]가 나온 이유가 뭘까?

[Result<success, failure>]의 경우 결과의 명시성이 향상된다. 확실히 복잡한 케이스가 있는 경우에는 switch를 사용해서 success, failure 케이스를 나누는 것이 좀 더 가독성이 좋다. (특히 failure의 케이스가 여러개로 나뉠 경우에 !)

하지만, 기존에 try-catch를 써왔기 때문에 코드가 둘이 섞인 경우에는 개인적으로 보기 좀 불편해서, 한 함수라면 둘 중 하나로 통일을 하는 게 좋겠다는 생각을 했다. 한 프로젝트에 하나로 통일하면 좋지 않을까?라는 생각을 했지만, try-catch 문의 경우에 Result보다 가볍게 사용하기 좋아서 간단한 에러 처리를 할 때에는 Result보다 try-catch문을 사용하는 게 좋겠다는 생각을 했다. (만약 생각이 다르다면, 댓글 부탁드립니다)

 

 try-catch문/ Result를 사용법 ! 

1️⃣  Result<Success, Failure>

2에서 [💡질문 ]에서 했던 질문을 해결할 수 있는 코드를 작성했다.

return 값을 Result로 함으로, .success와 .failure 케이스를 구분해서 title에 "NEW TEXT!"만, 아니라면 각 케이스에 맞게 error만을 반환할 수 있게 되었고, 이를 Viewmodel에는 Switch문을 통해서 케이스를 구분할 수 있게 되었다.

 

2️⃣  try-catch 문

우선 getTitle3()에 throws라는 문구를 넣었다. 이 뜻은 getTitle3()를 실행하는데, 만약 실패할 경우 Error를 던진다! 라는 의미이다.

 

그리고 getTitle3를 호출하는 fetchTitle()부분에서는 do 블록 안에 try를 앞에 작성하고 getTitle3() 함수를 호출한다. 이 말은 getTitle3()를 일단 시도해볼게! 라는 의미이다.

앞서 이야기 한 것처럼 getTitle3()는 성공하는 경우 "NEW TEXT!"를 반환하지만, 실패하는 경우에는 error를 반환한다. 이를 처리 하기 위해서 try한 getTitle3() 함수가 실패한 경우에는 catch 문으로 이동해서 error를 받아 해결하게 된다.

 

⚠️ try-catch문 추가내용

try-catch문에는 함정이 숨겨져 있다 ^^

아래에 알아야 하는 케이스들을 정리했다. 

case1) do에서 try한 게 실패할 시 try 이후의 코드는 실행되지 않음을 알 수 있다.

case2) error에 어떤 Error가 들어오든 신경쓰지 않을 때는 try?를 통해서 실패한 경우에는 nil값을 반환하게 만들 수 있다. 사실 try!도 가능하기는 하지만, !는 언제나 위험이 따르기 때문에 추천되는 방법은 아니다.

case3) 처음 실행했던 getTitle3가 실행되고 error가 반환되더라도, case1과 달리 아래의 코드는 계속 실행된다. 이는 순수한 try가 아니라 try?이기 때문이다.

 

 🔮 더 알아보기 

error의 종류가 여러개인 경우의 try-catch문, result 코드를 작성해보면 좀 더 에러처리에 친숙해질 것이다 ! 예시는 구글링하면 많이 찾아볼 수 있다. result의 경우 .get() 함수도 알아보면 좋을 듯 !

 

 🔮 출처 

https://developer.apple.com/documentation/swift/result

https://youtu.be/ss50RX7F7nE?si=qmvkjBL47BkOSPrs

반응형
Comments