Skip to content

Commit

Permalink
🐝 添加全局异常处理
Browse files Browse the repository at this point in the history
  • Loading branch information
newbee-mall committed Nov 10, 2019
1 parent 24b5e0a commit fab305e
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 27 deletions.
21 changes: 21 additions & 0 deletions src/main/java/ltd/newbee/mall/common/NewBeeMallException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ltd.newbee.mall.common;

public class NewBeeMallException extends RuntimeException {

public NewBeeMallException() {
}

public NewBeeMallException(String message) {
super(message);
}

/**
* 丢出一个异常
*
* @param message
*/
public static void fail(String message) {
throw new NewBeeMallException(message);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package ltd.newbee.mall.controller.common;

import ltd.newbee.mall.common.NewBeeMallException;
import ltd.newbee.mall.util.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

/**
* newbee-mall全局异常处理
*/
@RestControllerAdvice
public class NewBeeMallExceptionHandler {

@ExceptionHandler(Exception.class)
public Object handleException(Exception e, HttpServletRequest req) {
Result result = new Result();
result.setResultCode(500);
//区分是否为自定义异常
if (e instanceof NewBeeMallException) {
result.setMessage(e.getMessage());
} else {
result.setMessage("未知异常,请联系管理员");
}
//检查请求是否为ajax, 如果是 ajax 请求则返回 Result json串, 如果不是 ajax 请求则返回 error 视图
String contentTypeHeader = req.getHeader("Content-Type");
String acceptHeader = req.getHeader("Accept");
String xRequestedWith = req.getHeader("X-Requested-With");
if ((contentTypeHeader != null && contentTypeHeader.contains("application/json"))
|| (acceptHeader != null && acceptHeader.contains("application/json"))
|| "XMLHttpRequest".equalsIgnoreCase(xRequestedWith)) {
return result;
} else {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", e.getMessage());
modelAndView.addObject("url", req.getRequestURL());
modelAndView.addObject("stackTrace", e.getStackTrace());
modelAndView.addObject("author", "十三");
modelAndView.addObject("ltd", "新峰商城");
modelAndView.setViewName("error/error");
return modelAndView;
}
}
}
22 changes: 7 additions & 15 deletions src/main/java/ltd/newbee/mall/controller/mall/OrderController.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ltd.newbee.mall.controller.mall;

import ltd.newbee.mall.common.Constants;
import ltd.newbee.mall.common.NewBeeMallException;
import ltd.newbee.mall.common.ServiceResultEnum;
import ltd.newbee.mall.controller.vo.NewBeeMallOrderDetailVO;
import ltd.newbee.mall.controller.vo.NewBeeMallShoppingCartItemVO;
Expand Down Expand Up @@ -62,25 +63,16 @@ public String saveOrder(HttpSession httpSession) {
List<NewBeeMallShoppingCartItemVO> myShoppingCartItems = newBeeMallShoppingCartService.getMyShoppingCartItems(user.getUserId());
if (StringUtils.isEmpty(user.getAddress().trim())) {
//无收货地址
return "error/error_5xx";
NewBeeMallException.fail(ServiceResultEnum.NULL_ADDRESS_ERROR.getResult());
}
if (CollectionUtils.isEmpty(myShoppingCartItems)) {
//购物车中无数据则跳转至错误页
return "error/error_5xx";
} else {
//保存订单并返回订单号
String saveOrderResult = newBeeMallOrderService.saveOrder(user, myShoppingCartItems);
if (ServiceResultEnum.ORDER_PRICE_ERROR.getResult().equals(saveOrderResult)
|| ServiceResultEnum.ORDER_PRICE_ERROR.getResult().equals(saveOrderResult)
|| ServiceResultEnum.DB_ERROR.getResult().equals(saveOrderResult)
|| ServiceResultEnum.SHOPPING_ITEM_COUNT_ERROR.getResult().equals(saveOrderResult)
|| ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult().equals(saveOrderResult)) {
//订单生成失败
return "error/error_5xx";
}
//跳转到订单详情页
return "redirect:/orders/" + saveOrderResult;
NewBeeMallException.fail(ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult());
}
//保存订单并返回订单号
String saveOrderResult = newBeeMallOrderService.saveOrder(user, myShoppingCartItems);
//跳转到订单详情页
return "redirect:/orders/" + saveOrderResult;
}

@PutMapping("/orders/{orderNo}/cancel")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package ltd.newbee.mall.service.impl;

import ltd.newbee.mall.common.NewBeeMallOrderStatusEnum;
import ltd.newbee.mall.common.PayStatusEnum;
import ltd.newbee.mall.common.PayTypeEnum;
import ltd.newbee.mall.common.ServiceResultEnum;
import ltd.newbee.mall.common.*;
import ltd.newbee.mall.controller.vo.*;
import ltd.newbee.mall.dao.NewBeeMallGoodsMapper;
import ltd.newbee.mall.dao.NewBeeMallOrderItemMapper;
Expand Down Expand Up @@ -188,11 +185,11 @@ public String saveOrder(NewBeeMallUserVO user, List<NewBeeMallShoppingCartItemVO
for (NewBeeMallShoppingCartItemVO shoppingCartItemVO : myShoppingCartItems) {
//查出的商品中不存在购物车中的这条关联商品数据,直接返回错误提醒
if (!newBeeMallGoodsMap.containsKey(shoppingCartItemVO.getGoodsId())) {
return ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult();
NewBeeMallException.fail(ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult());
}
//存在数量大于库存的情况,直接返回错误提醒
if (shoppingCartItemVO.getGoodsCount() > newBeeMallGoodsMap.get(shoppingCartItemVO.getGoodsId()).getStockNum()) {
return ServiceResultEnum.SHOPPING_ITEM_COUNT_ERROR.getResult();
NewBeeMallException.fail(ServiceResultEnum.SHOPPING_ITEM_COUNT_ERROR.getResult());
}
}
//删除购物项
Expand All @@ -201,7 +198,7 @@ public String saveOrder(NewBeeMallUserVO user, List<NewBeeMallShoppingCartItemVO
List<StockNumDTO> stockNumDTOS = BeanUtil.copyList(myShoppingCartItems, StockNumDTO.class);
int updateStockNumResult = newBeeMallGoodsMapper.updateStockNum(stockNumDTOS);
if (updateStockNumResult < 1) {
return ServiceResultEnum.SHOPPING_ITEM_COUNT_ERROR.getResult();
NewBeeMallException.fail(ServiceResultEnum.SHOPPING_ITEM_COUNT_ERROR.getResult());
}
//生成订单号
String orderNo = NumberUtil.genOrderNo();
Expand All @@ -216,7 +213,7 @@ public String saveOrder(NewBeeMallUserVO user, List<NewBeeMallShoppingCartItemVO
priceTotal += newBeeMallShoppingCartItemVO.getGoodsCount() * newBeeMallShoppingCartItemVO.getSellingPrice();
}
if (priceTotal < 1) {
return ServiceResultEnum.ORDER_PRICE_ERROR.getResult();
NewBeeMallException.fail(ServiceResultEnum.ORDER_PRICE_ERROR.getResult());
}
newBeeMallOrder.setTotalPrice(priceTotal);
//todo 订单body字段,用来作为生成支付单描述信息,暂时未接入第三方支付接口,故该字段暂时设为空字符串
Expand All @@ -239,12 +236,13 @@ public String saveOrder(NewBeeMallUserVO user, List<NewBeeMallShoppingCartItemVO
//所有操作成功后,将订单号返回,以供Controller方法跳转到订单详情
return orderNo;
}
return ServiceResultEnum.ORDER_GENERATE_ERROR.getResult();
NewBeeMallException.fail(ServiceResultEnum.ORDER_PRICE_ERROR.getResult());
}
return ServiceResultEnum.DB_ERROR.getResult();
NewBeeMallException.fail(ServiceResultEnum.DB_ERROR.getResult());
}
return ServiceResultEnum.DB_ERROR.getResult();
NewBeeMallException.fail(ServiceResultEnum.DB_ERROR.getResult());
}
NewBeeMallException.fail(ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult());
return ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult();
}

Expand Down Expand Up @@ -368,4 +366,4 @@ public List<NewBeeMallOrderItemVO> getOrderItems(Long id) {
}
return null;
}
}
}
25 changes: 25 additions & 0 deletions src/main/resources/templates/error/error.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>NEW BEE ERROR PAGE</title>
<style type="text/css">/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}/*! Simple HttpErrorPages | MIT X11 License | https://github.com/AndiDittrich/HttpErrorPages */body,html{width:100%;height:100%;background-color:#21232a}body{color:#fff;text-shadow:0 2px 4px rgba(0,0,0,.5);padding:0;min-height:100%;-webkit-box-shadow:inset 0 0 100px rgba(0,0,0,.8);box-shadow:inset 0 0 100px rgba(0,0,0,.8);display:table;font-family:"Open Sans",Arial,sans-serif}h1{font-family:inherit;font-weight:500;line-height:1.1;color:inherit;font-size:36px}h1 small{font-size:68%;font-weight:400;line-height:1;color:#777}a{text-decoration:none;color:#fff;font-size:inherit;border-bottom:dotted 1px #707070}.lead{color:silver;font-size:21px;line-height:1.4}.cover{display:table-cell;vertical-align:middle;padding:0 20px}footer{position:fixed;width:100%;height:40px;left:0;bottom:0;color:#a0a0a0;font-size:14px}</style>
</head>
<body>
<div class="cover">
<h1>你的请求出错了</h1>
<p th:text="'错误信息:'+${message}" style="color: red;font-weight: 600;"></p>
<p th:text="'请求地址:'+${url}"></p>
<h2>报告问题</h2>
<a href="https://github.com/newbee-ltd/newbee-mall/issues/new" target="_blank" style="color: #1baeae">提交issue</a>&nbsp;&nbsp;&nbsp;&nbsp;
<a href="//shang.qq.com/wpa/qunwpa?idkey=dc0e028f177932aee2c212a2dd60e0b8342042ac205305803ea801c4eea6727c" target="_blank" style="color: #1baeae">QQ交流群</a>
<h2>异常堆栈跟踪日志</h2>
<div th:each="string:${stackTrace}">
<small><th:block th:text="${string}"></th:block></small>
</div>
<h2>Copy Right</h2>
<p th:text="'author:'+${author}" style="color: #1baeae;"></p>
<p th:text="'ltd:'+${ltd}" style="color: #1baeae;"></p>
</div>
</body>
</html>

0 comments on commit fab305e

Please sign in to comment.