diff --git a/lib/presentation/view_models/add_restaurant_view_model.dart b/lib/presentation/view_models/add_restaurant_view_model.dart index cd34f01..b0a5568 100644 --- a/lib/presentation/view_models/add_restaurant_view_model.dart +++ b/lib/presentation/view_models/add_restaurant_view_model.dart @@ -8,6 +8,15 @@ import '../providers/di_providers.dart'; import '../providers/restaurant_provider.dart'; import '../providers/location_provider.dart'; +/// 지오코딩 실패 시 발생하는 예외 +class GeocodingException implements Exception { + final String message; + const GeocodingException(this.message); + + @override + String toString() => message; +} + /// 식당 추가 화면의 상태 모델 class AddRestaurantState { final bool isLoading; @@ -128,10 +137,23 @@ class RestaurantFormData { jibunAddress: jibunAddressController.text.trim(), latitude: latitudeController.text.trim(), longitude: longitudeController.text.trim(), - naverUrl: naverUrlController.text.trim(), + naverUrl: _extractNaverUrl(naverUrlController.text.trim()), ); } + /// 공유 텍스트에서 네이버 지도 URL만 추출 + static String _extractNaverUrl(String text) { + if (text.isEmpty) return ''; + + // URL 패턴 추출 + final urlRegex = RegExp( + r'(https?://(?:map\.naver\.com|naver\.me)[^\s]+)', + caseSensitive: false, + ); + final match = urlRegex.firstMatch(text); + return match?.group(0) ?? text; + } + /// Restaurant 엔티티로부터 폼 데이터 생성 factory RestaurantFormData.fromRestaurant(Restaurant restaurant) { return RestaurantFormData( @@ -351,7 +373,11 @@ class AddRestaurantViewModel extends StateNotifier { state = state.copyWith(isLoading: false); return true; } catch (e) { - state = state.copyWith(isLoading: false, errorMessage: e.toString()); + // GeocodingException은 이미 사용자 친화적 메시지가 설정됨 + final message = e is GeocodingException + ? e.message + : '저장 중 오류가 발생했습니다. 다시 시도해주세요.'; + state = state.copyWith(isLoading: false, errorMessage: message); return false; } } @@ -474,12 +500,9 @@ class AddRestaurantViewModel extends StateNotifier { ); if (!allowFallbackWhenGeocodingFails) { - state = state.copyWith( - errorMessage: - '주소가 지도에서 인식되지 않습니다. ' - '도로명 주소 전체를 정확히 입력했는지 확인해 주세요.', - ); - throw Exception('지오코딩 실패: $address'); + const userMessage = '위치 정보를 가져올 수 없습니다. 주소를 확인해주세요.'; + state = state.copyWith(errorMessage: userMessage); + throw GeocodingException(userMessage); } } }