package com.mosty.common.base.exception;

import com.mosty.common.base.domain.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.stereotype.Component;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;
import java.util.stream.Collectors;

/**
 *  全局异常处理
 * @author kevin
 * @date 2022/2/22 1:50 PM
 * @since 1.0.0
 */
@Slf4j
@Component
@SuppressWarnings("unused")
@ControllerAdvice(basePackages = "com.mosty")
public class MostyExceptionHandler {

    /**
     *  业务异常捕获
     *  需要使用spring mvc的全局异常拦截器处理
     * @param throwable 全局异常
     * @return 信息体
     */
    @ResponseBody
    @ExceptionHandler(Throwable.class)
    public ResponseResult<String> throwableHandler(Throwable throwable) {
        throwable.printStackTrace();
        log.warn("throwable异常：message={}", throwable.getMessage());
        log.warn("throwable异常：stack={}", throwable.getStackTrace());
        return ResponseResult.fail("系统异常，请稍后重试");
    }

    /**
     *  spring valid框架验证器异常捕获
     *  需要使用spring mvc的全局异常拦截器处理
     * @param validException 验证异常
     * @return 信息体
     */
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseResult<String> validHandler(MethodArgumentNotValidException validException) {
        StringBuilder sb = new StringBuilder();
        List<ObjectError> allErrors = validException.getBindingResult().getAllErrors();
        String message = allErrors.stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(";"));
        log.warn("调用接口验证异常：message={}", message);
        return ResponseResult.fail(message);
    }

    /**
     *  业务异常捕获
     *  需要使用spring mvc的全局异常拦截器处理
     * @param businessException 业务异常
     * @return 信息体
     */
    @ResponseBody
    @ExceptionHandler(BusinessException.class)
    public ResponseResult<String> businessHandler(BusinessException businessException) {
        log.warn("业务异常：message={}", businessException.getMessage());
        if (businessException.getCode() != null) {
            return ResponseResult.fail(businessException.getCode(), businessException.getMessage());
        }
        return ResponseResult.fail(businessException.getMessage());
    }

}
