Java와 Go로 개발하다 보니 묘한 생각이 들어 쓰는 글.
결론적으로 실패 처리의 소유권에 대한 이야기
실패 시 예외로 처리
주로 Java, Spring 진영에서 사용
비즈니스 로직 집중도가 높음
코드가 짧고 깔끔함
Spring의 @ControllerAdvice와 잘 어울림
예외 흐름을 모르면 전체 로직 이해가 어려움
예외가 많아지면 추적이 힘들어짐
@Service
public class OrderService {
public void placeOrder(String token, Long productId) {
User user = authService.authenticate(token); // 실패 시 예외
Product product = productService.getProduct(productId); // 없으면 예외
orderValidator.validateOrderable(user, product); // 검증 실패 시 예외
Order order = Order.create(user, product);
orderRepository.save(order);
}
}
실패 가능성은 초반에 모두 제거
모든 에러는 명시적으로 처리
숨겨진 흐름이 없음
에러 발생 지점을 바로 알 수 있음
디버깅이 쉬움
함수의 계약(contract)이 명확
코드가 길어질 수 있음
성공 흐름이 중간중간 끊겨 보일 수 있음
func PlaceOrder(token string, productID int64) error {
user, err := auth.Authenticate(token)
if err != nil {
return err
}
product, err := product.Get(productID)
if err != nil {
return err
}
if !order.CanOrder(user, product) {
return errors.New("order not allowed")
}
order := NewOrder(user, product)
if err := repository.Save(order); err != nil {
return err
}
return nil
}
| 항목 | Happy Path (Java) | Fail Fast (Go) |
|---|---|---|
| 실패 처리 | Exception | error 반환 |
| 흐름 중심 | 성공 시나리오 | 실패 제거 |
| 가독성 | 비즈니스 중심 | 조건 중심 |
| 에러 노출 | 암묵적 | 명시적 |
| 중첩 | 적음 | 거의 없음 |
사실상 언어가 철학을 강제한다고 볼 수 있다.
필자는 개인적으로 Go 방식이 더 마음에 들었다.
예외를 일일이 신경써야 하는 점이 개발할 때 피곤하기도 한데 그래서 좀 재밌는 면이 있는 것 같다. 원시적인 느낌...