ResultException.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. package jnpf.exception;
  2. import cn.dev33.satoken.exception.SameTokenInvalidException;
  3. import cn.dev33.satoken.exception.NotLoginException;
  4. import cn.dev33.satoken.exception.NotPermissionException;
  5. import cn.dev33.satoken.exception.NotRoleException;
  6. import cn.hutool.http.useragent.UserAgent;
  7. import cn.hutool.http.useragent.UserAgentUtil;
  8. import com.alibaba.fastjson.JSON;
  9. import jnpf.base.ActionResult;
  10. import jnpf.base.ActionResultCode;
  11. import jnpf.base.UserInfo;
  12. import jnpf.config.ConfigValueUtil;
  13. import jnpf.constant.MsgCode;
  14. import jnpf.database.util.NotTenantPluginHolder;
  15. import jnpf.database.util.TenantDataSourceUtil;
  16. import jnpf.entity.LogEntity;
  17. import jnpf.service.LogService;
  18. import jnpf.util.*;
  19. import lombok.extern.slf4j.Slf4j;
  20. import org.springframework.beans.factory.annotation.Autowired;
  21. import org.springframework.boot.autoconfigure.web.ErrorProperties;
  22. import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
  23. import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
  24. import org.springframework.http.HttpStatus;
  25. import org.springframework.http.ResponseEntity;
  26. import org.springframework.stereotype.Controller;
  27. import org.springframework.validation.ObjectError;
  28. import org.springframework.web.bind.MethodArgumentNotValidException;
  29. import org.springframework.web.bind.annotation.ControllerAdvice;
  30. import org.springframework.web.bind.annotation.ExceptionHandler;
  31. import org.springframework.web.bind.annotation.RequestMapping;
  32. import org.springframework.web.bind.annotation.ResponseBody;
  33. import jakarta.servlet.ServletException;
  34. import jakarta.servlet.http.HttpServletRequest;
  35. import java.util.Date;
  36. import java.util.HashMap;
  37. import java.util.List;
  38. import java.util.Map;
  39. /**
  40. * @author JNPF开发平台组
  41. * @version V3.1.0
  42. * @copyright 引迈信息技术有限公司
  43. * @date 2021/3/16 10:10
  44. */
  45. @Slf4j
  46. @Controller
  47. @ControllerAdvice
  48. public class ResultException extends BasicErrorController {
  49. @Autowired
  50. private LogService logService;
  51. @Autowired
  52. private ConfigValueUtil configValueUtil;
  53. public ResultException(){
  54. super(new DefaultErrorAttributes(), new ErrorProperties());
  55. }
  56. @ResponseBody
  57. @ExceptionHandler(value = LoginException.class)
  58. public ActionResult loginException(LoginException e) {
  59. ActionResult result = ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage());
  60. result.setData(e.getData());
  61. return result;
  62. }
  63. /**
  64. * 简单异常处理
  65. */
  66. @ResponseBody
  67. @ExceptionHandler(value = {ImportException.class, DataException.class, EncryptFailException.class})
  68. public ActionResult simpleException(Exception e) {
  69. ActionResult result = ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage());
  70. return result;
  71. }
  72. // @ResponseBody
  73. // @ExceptionHandler(value = FileNotException.class)
  74. // public ActionResult loginException(FileNotException e) {
  75. // ActionResult result = ActionResult.fail(ActionResultCode.Fail.getCode(), "文件不存在");
  76. // return result;
  77. // }
  78. /**
  79. * 租户数据库异常
  80. *
  81. * @param e
  82. * @return
  83. */
  84. @ResponseBody
  85. @ExceptionHandler(value = {TenantDatabaseException.class, TenantInvalidException.class})
  86. public ActionResult<String> tenantDatabaseException(TenantInvalidException e) {
  87. String msg;
  88. if(e.getMessage() == null){
  89. if (configValueUtil.getMultiTenancyUrl().contains("https")) {
  90. // https 官网提示
  91. msg = MsgCode.LOG109.get();
  92. } else {
  93. msg = MsgCode.LOG110.get();
  94. }
  95. }else{
  96. msg = e.getMessage();
  97. }
  98. if(e.getLogMsg() != null){
  99. log.error(e.getLogMsg());
  100. }
  101. return ActionResult.fail(ActionResultCode.Fail.getCode(), msg);
  102. }
  103. ///
  104. // @ResponseBody
  105. // @ExceptionHandler(value = SQLSyntaxErrorException.class)
  106. // public ActionResult sqlException(SQLSyntaxErrorException e) {
  107. // ActionResult result;
  108. // log.error(e.getMessage());
  109. // e.printStackTrace();
  110. // if (e.getMessage().contains("Unknown database")) {
  111. // printLog(e, "请求失败");
  112. // result = ActionResult.fail(ActionResultCode.Fail.getCode(), "请求失败");
  113. // } else {
  114. // printLog(e, "数据库异常");
  115. // result = ActionResult.fail(ActionResultCode.Fail.getCode(), "数据库异常");
  116. // }
  117. // return result;
  118. // }
  119. //
  120. // @ResponseBody
  121. // @ExceptionHandler(value = SQLServerException.class)
  122. // public ActionResult sqlServerException(SQLServerException e) {
  123. // ActionResult result;
  124. // printLog(e, "系统异常");
  125. // if (e.getMessage().contains("将截断字符串")) {
  126. // printLog(e, "某个字段字符长度超过限制,请检查。");
  127. // result = ActionResult.fail(ActionResultCode.Fail.getCode(), "某个字段字符长度超过限制,请检查。");
  128. // } else {
  129. // log.error(e.getMessage());
  130. // printLog(e, "数据库异常,请检查。");
  131. // result = ActionResult.fail(ActionResultCode.Fail.getCode(), "数据库异常,请检查。");
  132. // }
  133. // return result;
  134. // }
  135. @ResponseBody
  136. @ExceptionHandler(value = MethodArgumentNotValidException.class)
  137. public ActionResult methodArgumentNotValidException(MethodArgumentNotValidException e) {
  138. Map<String, String> map = new HashMap<>(16);
  139. List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
  140. for (int i = 0; i < allErrors.size(); i++) {
  141. String s = allErrors.get(i).getCodes()[0];
  142. //用分割的方法得到字段名
  143. String[] parts = s.split("\\.");
  144. String part1 = parts[parts.length - 1];
  145. map.put(part1, allErrors.get(i).getDefaultMessage());
  146. }
  147. String json = JSON.toJSONString(map);
  148. ActionResult result = ActionResult.fail(ActionResultCode.ValidateError.getCode(), json);
  149. printLog(e, "字段验证异常", 4);
  150. return result;
  151. }
  152. @ResponseBody
  153. @ExceptionHandler(value = WorkFlowException.class)
  154. public ActionResult workFlowException(WorkFlowException e) {
  155. if (e.getCode() == 200) {
  156. Map<String, Object> map = JsonUtil.stringToMap(e.getMessage());
  157. return ActionResult.success(map);
  158. } else {
  159. if(e.getSuppressed()!=null) {
  160. printLog(e, "系统异常", 4);
  161. }
  162. return ActionResult.fail(e.getMessage());
  163. }
  164. }
  165. @ResponseBody
  166. @ExceptionHandler(value = WxErrorException.class)
  167. public ActionResult wxErrorException(WxErrorException e) {
  168. return ActionResult.fail(e.getError().getErrorCode(), MsgCode.AD103.get());
  169. }
  170. @ResponseBody
  171. @ExceptionHandler(value = ServletException.class)
  172. public void exception(ServletException e) throws Exception {
  173. log.error("系统异常:" + e.getMessage(), e);
  174. printLog(e, "系统异常", 4);
  175. throw new Exception();
  176. }
  177. @ResponseBody
  178. @ExceptionHandler(value = Exception.class)
  179. public ActionResult exception(Exception e) {
  180. log.error("系统异常:" + e.getMessage(), e);
  181. printLog(e, "系统异常", 4);
  182. if(e instanceof ConnectDatabaseException || e.getCause() instanceof ConnectDatabaseException){
  183. Throwable t = e;
  184. if(e.getCause() instanceof ConnectDatabaseException){
  185. t = e.getCause();
  186. }
  187. return ActionResult.fail(ActionResultCode.Fail.getCode(), t.getMessage());
  188. }
  189. return ActionResult.fail(ActionResultCode.Fail.getCode(), MsgCode.AD102.get());
  190. }
  191. /**
  192. * 权限码异常
  193. */
  194. @ResponseBody
  195. @ExceptionHandler(NotPermissionException.class)
  196. public ActionResult<Void> handleNotPermissionException(NotPermissionException e) {
  197. return ActionResult.fail(ActionResultCode.Fail.getCode(), MsgCode.AD104.get());
  198. }
  199. /**
  200. * 角色权限异常
  201. */
  202. @ResponseBody
  203. @ExceptionHandler(NotRoleException.class)
  204. public ActionResult<Void> handleNotRoleException(NotRoleException e) {
  205. return ActionResult.fail(ActionResultCode.ValidateError.getCode(), MsgCode.AD104.get());
  206. }
  207. /**
  208. * 认证失败
  209. */
  210. @ResponseBody
  211. @ExceptionHandler(NotLoginException.class)
  212. public ActionResult<Void> handleNotLoginException(NotLoginException e) {
  213. return ActionResult.fail(ActionResultCode.SessionOverdue.getCode(), MsgCode.AD105.get());
  214. }
  215. /**
  216. * 无效认证
  217. */
  218. @ResponseBody
  219. @ExceptionHandler(SameTokenInvalidException.class)
  220. public ActionResult<Void> handleIdTokenInvalidException(SameTokenInvalidException e) {
  221. return ActionResult.fail(ActionResultCode.SessionOverdue.getCode(), MsgCode.AD106.get());
  222. }
  223. private void printLog(Exception e, String msg, int type) {
  224. try {
  225. UserInfo userInfo = UserProvider.getUser();
  226. if (userInfo.getId() == null) {
  227. e.printStackTrace();
  228. return;
  229. }
  230. //接口错误将不会进入数据库切源拦截器需要手动设置
  231. if (configValueUtil.isMultiTenancy() && TenantHolder.getDatasourceId() == null) {
  232. try {
  233. TenantDataSourceUtil.switchTenant(userInfo.getTenantId());
  234. } catch (Exception ee){
  235. e.printStackTrace();
  236. return;
  237. }
  238. }
  239. LogEntity entity = new LogEntity();
  240. entity.setId(RandomUtil.uuId());
  241. entity.setUserId(userInfo.getUserId());
  242. entity.setUserName(userInfo.getUserName() + "/" + userInfo.getUserAccount());
  243. // if (!ServletUtil.getIsMobileDevice()) {
  244. entity.setDescription(msg);
  245. // }
  246. StringBuilder sb = new StringBuilder();
  247. sb.append(e.toString() + "\n");
  248. StackTraceElement[] stackArray = e.getStackTrace();
  249. for (int i = 0; i < stackArray.length; i++) {
  250. StackTraceElement element = stackArray[i];
  251. sb.append(element.toString() + "\n");
  252. }
  253. entity.setJsons(sb.toString());
  254. entity.setRequestUrl(ServletUtil.getRequest().getServletPath());
  255. entity.setRequestMethod(ServletUtil.getRequest().getMethod());
  256. entity.setType(type);
  257. entity.setUserId(userInfo.getUserId());
  258. // ip
  259. String ipAddr = IpUtil.getIpAddr();
  260. entity.setIpAddress(ipAddr);
  261. entity.setIpAddressName(IpUtil.getIpCity(ipAddr));
  262. entity.setCreatorTime(new Date());
  263. UserAgent userAgent = UserAgentUtil.parse(ServletUtil.getUserAgent());
  264. if (userAgent != null) {
  265. entity.setPlatForm(userAgent.getPlatform().getName() + " " + userAgent.getOsVersion());
  266. entity.setBrowser(userAgent.getBrowser().getName() + " " + userAgent.getVersion());
  267. }
  268. if (configValueUtil.isMultiTenancy() && StringUtil.isEmpty(TenantHolder.getDatasourceId())) {
  269. log.error("请求异常, 无登陆租户:" + ReflectionUtil.toString(entity), e);
  270. } else {
  271. logService.save(entity);
  272. }
  273. }catch (Exception g){
  274. log.error(g.getMessage());
  275. }finally {
  276. UserProvider.clearLocalUser();
  277. TenantProvider.clearBaseSystemIfo();
  278. TenantDataSourceUtil.clearLocalTenantInfo();
  279. NotTenantPluginHolder.clearNotSwitchFlag();
  280. }
  281. }
  282. /**
  283. * 覆盖默认的JSON响应
  284. */
  285. @Override
  286. @RequestMapping
  287. public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
  288. HttpStatus status = getStatus(request);
  289. if (status == HttpStatus.NOT_FOUND) {
  290. return new ResponseEntity<>(status);
  291. }
  292. return super.error(request);
  293. }
  294. /**
  295. * 权限异常
  296. * @param e
  297. * @return
  298. */
  299. @ResponseBody
  300. @ExceptionHandler(value = NoPermiLoginException.class)
  301. public ActionResult NoPermiLoginException(NoPermiLoginException e) {
  302. ActionResult result = ActionResult.fail(ActionResultCode.PeimissionExp.getCode(), e.getMessage());
  303. result.setData(e.getData());
  304. return result;
  305. }
  306. }