package kr.co.vividnext.sodalive.common import kr.co.vividnext.sodalive.i18n.Lang import kr.co.vividnext.sodalive.i18n.LangContext import kr.co.vividnext.sodalive.i18n.SodaMessageSource import org.slf4j.LoggerFactory import org.springframework.dao.DataIntegrityViolationException import org.springframework.http.HttpStatus import org.springframework.security.access.AccessDeniedException import org.springframework.security.authentication.BadCredentialsException import org.springframework.security.authentication.InternalAuthenticationServiceException import org.springframework.web.bind.annotation.ExceptionHandler import org.springframework.web.bind.annotation.ResponseStatus import org.springframework.web.bind.annotation.RestControllerAdvice import org.springframework.web.multipart.MaxUploadSizeExceededException import org.springframework.web.server.ResponseStatusException @RestControllerAdvice class SodaExceptionHandler( private val langContext: LangContext, private val messageSource: SodaMessageSource ) { private val logger = LoggerFactory.getLogger(this::class.java) private val logLang = Lang.KO @ExceptionHandler(SodaException::class) fun handleSodaException(e: SodaException) = run { val logMessage = e.messageKey?.takeIf { it.isNotBlank() }?.let { messageSource.getMessage(it, logLang) } ?: e.message?.takeIf { it.isNotBlank() } ?: messageSource.getMessage("common.error.unknown", logLang) logger.error("API error: {}", logMessage, e) val message = e.messageKey?.takeIf { it.isNotBlank() }?.let { messageSource.getMessage(it, langContext.lang) } ?: e.message?.takeIf { it.isNotBlank() } ?: messageSource.getMessage("common.error.unknown", langContext.lang) ApiResponse.error( message = message, errorProperty = e.errorProperty ) } @ExceptionHandler(MaxUploadSizeExceededException::class) fun handleMaxUploadSizeExceededException(e: MaxUploadSizeExceededException) = run { val logMessage = messageSource.getMessage("common.error.max_upload_size", logLang) logger.error("API error: {}", logMessage, e) val message = messageSource.getMessage("common.error.max_upload_size", langContext.lang) ApiResponse.error(message = message) } @ExceptionHandler(AccessDeniedException::class) fun handleAccessDeniedException(e: AccessDeniedException) = run { val logMessage = messageSource.getMessage("common.error.access_denied", logLang) logger.error("API error: {}", logMessage, e) val message = messageSource.getMessage("common.error.access_denied", langContext.lang) ApiResponse.error(message = message) } @ExceptionHandler(InternalAuthenticationServiceException::class) fun handleInternalAuthenticationServiceException(e: InternalAuthenticationServiceException) = run { val logMessage = messageSource.getMessage("common.error.bad_credentials", logLang) logger.error("API error: {}", logMessage, e) val message = messageSource.getMessage("common.error.bad_credentials", langContext.lang) ApiResponse.error(message) } @ExceptionHandler(BadCredentialsException::class) fun handleBadCredentialsException(e: BadCredentialsException) = run { val logMessage = messageSource.getMessage("common.error.bad_credentials", logLang) logger.error("API error: {}", logMessage, e) val message = messageSource.getMessage("common.error.bad_credentials", langContext.lang) ApiResponse.error(message) } @ExceptionHandler(DataIntegrityViolationException::class) fun handleDataIntegrityViolationException(e: DataIntegrityViolationException) = run { val logMessage = messageSource.getMessage("common.error.already_registered", logLang) logger.error("API error: {}", logMessage, e) val message = messageSource.getMessage("common.error.already_registered", langContext.lang) ApiResponse.error(message) } @ResponseStatus(value = HttpStatus.NOT_FOUND) @ExceptionHandler(AdsChargeException::class) fun handleAdsChargeException(e: AdsChargeException) = run { val logMessage = e.messageKey?.takeIf { it.isNotBlank() }?.let { messageSource.getMessage(it, logLang) } ?: e.message?.takeIf { it.isNotBlank() } ?: messageSource.getMessage("common.error.invalid_request", logLang) logger.error("API error - AdsChargeException: {}", logMessage, e) val message = e.messageKey?.takeIf { it.isNotBlank() }?.let { messageSource.getMessage(it, langContext.lang) } ?: e.message?.takeIf { it.isNotBlank() } ?: messageSource.getMessage("common.error.invalid_request", langContext.lang) ApiResponse.error(message) } @ExceptionHandler(Exception::class) fun handleException(e: Exception) = run { if (e is ResponseStatusException) throw e val logMessage = messageSource.getMessage("common.error.unknown", logLang) logger.error("API error: {}", logMessage, e) val message = messageSource.getMessage("common.error.unknown", langContext.lang) ApiResponse.error(message) } }