Java Exception 捕获和展示

经常有这样的场景:后端处理业务逻辑,前端负责展示,当后端处理出现异常时,如何把错误信息展示给前台呢?错误信息栈通常很多,对开发人员查找问题比较方便,但对于客户来说,打一堆的错误信息,无疑是对他们感官的一种摧残,如何捕捉最重要的信息显示到客户端呢?该信息要求简明扼要,指向出错点,且应指明异常的类型。

        在很多情况下Exception的 getMessage()方法返回空的值,如果使用该方式则会在前端显示空值。我们要显示的重要信息有两个:

  •          异常类型
  •          出错点和出错信息

         

1、异常类型如何获得呢?

可以通过Exception 的getClass().getName()方法来实现。


2、出错点如何获得呢?

出错点信息一般在“Cause by:”标识开始的行。如果能抓取到该行,则可取出异常信息,一个异常栈例子如下:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Caused by: org.apache.activemq.selector.ParseException: Parse error at line 0, column 0.  Encountered: <EOF>  
  2.     at org.apache.activemq.selector.SelectorParser.generateParseException(SelectorParser.java:1231)  
  3.     at org.apache.activemq.selector.SelectorParser.jj_consume_token(SelectorParser.java:1179)  
  4.     at org.apache.activemq.selector.SelectorParser.unaryExpr(SelectorParser.java:468)  
  5.     at org.apache.activemq.selector.SelectorParser.multExpr(SelectorParser.java:390)  
  6.     at org.apache.activemq.selector.SelectorParser.addExpression(SelectorParser.java:359)  
  7.     at org.apache.activemq.selector.SelectorParser.comparisonExpression(SelectorParser.java:211)  
  8.     at org.apache.activemq.selector.SelectorParser.equalityExpression(SelectorParser.java:156)  
  9.     at org.apache.activemq.selector.SelectorParser.andExpression(SelectorParser.java:135)  
  10.     at org.apache.activemq.selector.SelectorParser.orExpression(SelectorParser.java:114)  
  11.     at org.apache.activemq.selector.SelectorParser.JmsSelector(SelectorParser.java:106)  
  12.     at org.apache.activemq.selector.SelectorParser.parse(SelectorParser.java:84)  
  13.     ... 63 more  

        由于一些原因,往往它并不出现在第一行,所以,通过取第一行的方式不能获取出错点和出错提示信息。

        如果自己解析该输出,一行一行地读入,然后通过判断首字符是否是“Caused by:” 也能抓取到出错点和出错信息。

        最简单的方式,还是使用正则表达式,可以比较简单地实现抓取出错点和出错信息。例如:

代码1:使用正则表达式获取出错点和出错信息

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. String regEx = "Caused by:(.*)";    
  2. Pattern pat = Pattern.compile(regEx);    
  3. Matcher mat = pat.matcher(content);    
  4. boolean rs = mat.find();    
  5. System.out.println("found?" + rs);  
  6. System.out.println(mat.group(1));  

代码1的结果输出:

org.apache.activemq.selector.ParseException: Parse error at line 0, column 0.  Encountered: <EOF>

3、异常信息的获取

         虽然知道了如何找出错点,但异常信息如何获得呢?Exception.printStrackTrace()中虽然有出错点信息,但都打到控制台上去了,Exception.getStackTrace(),并不能获得出错点的提示信息。

        一个应对办法就是捕获e.printStrackTrace()输出, 使用e.printStackTrace(PrintStream)方法,将异常栈信息先输出到ByteOutputStream ,然后再将ByteOutputStream 转换为字符串,就获得了异常的完整输出。代码为:

代码2:获取完整异常信息

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  2. e.printStackTrace(new PrintStream(baos));  
  3. String exception = baos.toString();  
  4. System.out.println("baos:" + exception);  



完整的测试代码--异常Caused by捕获(注:该测试代码中并没有出现Caused by字样,实际应用代码比较多,没有放进测试用例中):

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.io.ByteArrayOutputStream;  
  2. import java.io.File;  
  3. import java.io.FileInputStream;  
  4. import java.io.PrintStream;  
  5. import java.util.regex.Matcher;  
  6. import java.util.regex.Pattern;  
  7.   
  8. public class RegexpTest {  
  9.     /** 
  10.      * 读取文件中的内容 
  11.      * @return 
  12.      */  
  13.     public String readFile(){  
  14.         try {  
  15.             String fileName = "D:\\test2\\exception.log";  
  16.             File f = new File(fileName);  
  17.             FileInputStream fis = new FileInputStream(f);  
  18.             int filesize = fis.available();  
  19.             byte[] buffer = new byte[filesize];  
  20.             fis.read(buffer);  
  21.             return new String(buffer);  
  22.         } catch (Exception e) {  
  23.             e.printStackTrace();  
  24.             return null;  
  25.         }         
  26.     }  
  27.       
  28.     /** 
  29.      * 正则表达式测试 
  30.      */  
  31.     public void test(){  
  32.         try {  
  33.             String content = readFile();  
  34.             System.out.println(content);  
  35.               
  36.             String regEx = "Caused by:(.*)";    
  37.             Pattern pat = Pattern.compile(regEx);    
  38.             Matcher mat = pat.matcher(content);    
  39.             boolean rs = mat.find();    
  40.             System.out.println("found?" + rs);  
  41.             System.out.println(mat.group(1));  
  42. //          for(int i=1;i<=mat.groupCount();i++){    
  43. //              System.out.println("found:" + mat.group(i));    
  44. //          }     
  45.         } catch (Exception e) {  
  46.             e.printStackTrace();  
  47.         }  
  48.     }  
  49.       
  50.     public void test2(){  
  51.         try {  
  52.             FileInputStream fis = new FileInputStream("d:\\test.txt");  
  53.             fis.read();  
  54.         } catch (Exception e) {  
  55.             e.printStackTrace();  
  56.             ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  57.             e.printStackTrace(new PrintStream(baos));  
  58.             String exception = baos.toString();  
  59.             System.out.println("exception:" + exception);  
  60.         }  
  61.     }  
  62.       
  63.     public static void main(String[] args) {  
  64.         RegexpTest rt = new RegexpTest();  
  65.         //rt.test();  
  66.         rt.test2();  
  67.     }  

4、获取异常类型和出错点还有一种简单的方法

获取出错点类型:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. e.getCause().getClass()  

获取出错点信息(出错原因):

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. e.getCause().getMessage()  

代码示例(注:实际代码截取,不可直接运行):

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.     @SuppressWarnings("unchecked")  
  2.     @RequestMapping(value="/createSubscriber", method = RequestMethod.POST)  
  3.     public @ResponseBody  
  4.     WrappedResult createSubscriber(@ItemsRequestBody List<Map> list) {  
  5.         LocalBrokerFacade facade = new LocalBrokerFacade(BrokerRegistry.getInstance().findFirst());  
  6.         WrappedResult result = new WrappedResult();  
  7.         try {  
  8.             Map params = list.get(0);  
  9.             String clientId = (String)params.get("clientId");  
  10.             String subscriberName = (String)params.get("subscriberName");  
  11.             String topicName = (String)params.get("topicName");  
  12.             String selector = (String)params.get("selector");  
  13.               
  14. //          if("".equals(selector)){  
  15. //              selector = null;  
  16. //          }  
  17.               
  18.             facade.getBrokerAdmin().createDurableSubscriber(clientId,  
  19.                     subscriberName,topicName,selector);  
  20.             result.setSuccessful(true);  
  21.         } catch (Exception e) {  
  22.             System.out.println("Exception:" + e.getCause().getClass() + "," + e.getCause().getMessage());  
  23.             //log.error("createSubscriber failed.", e);  
  24.         }  



输出:Exception:class org.apache.activemq.selector.ParseException,Parse error at line 0, column 0.  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值