zoukankan      html  css  js  c++  java
  • 【PHP】什么时候使用Try Catch(转)

    几条建议:
       如果无法处理某个异常,那就不要捕获它。 
       如果捕获了一个异常,请不要胡乱处理它。 
       尽量在靠近异常被抛出的地方捕获异常。 
       在捕获异常的地方将它记录到日志中,除非您打算将它重新抛出。 
       按照您的异常处理必须多精细来构造您的方法。 
       需要用几种类型的异常就用几种,尤其是对于应用程序异常。
       把低层次的异常封装成层次较高程序员较容易理解的异常。
       尽量输出造成异常的完整数据
       尽量捕获具有特定含义的异常:比如SqlException,而不是简单地捕获一个Exception。

      如果你的程序不是对效率苛求得过分,我建议你宁可多使用一些异常也是好的。
    注意:我说的多使用的意思不是让你全部trycatch起来,然后catch(Exception e)把所有的异常都屏蔽了;而是暂时不考虑trycatch可能带来的效率上的损失,而注重程序的稳定性。
    至于如何优化trycatch的使用,慢慢来。就我个人的使用而言,影响其实不是很大。

        

    1.       不要滥用Try…Catch。一般来说只在最外层函数上才需要。因为该函数不能将Exception再往外抛了。所以需要Catch住做相应的处理,如显示Error Message。或转化为与调用模块约定好的Error Code。内部函数即使Catch住了Exception,也要往外抛,所以没有必要。

    2.       为了使用Finally来保证资源的释放。如:

    SqlConnection connection = null;

        try

        {

              connection = new SqlConnection(ConnectionString);

              connection.Open();

             …

        }

       catch (Exception ex)

        {

             throw ex;

        }

        finally

        {

             if (connection != null && connection.State != ConnectionState.Closed)

             {

                  connection.Close();

             }

    }

    对这种情况Catch住的Exception直接往外抛,不做处理。需要注意的是这里使用Try…Catch不是唯一的办法,也可以使用using语句来保证资源的释放。

    3.       为了保证函数有统一的出口。比如一个最外层的函数连续调用了一系列内部子函数,当其中某个子函数出错时, 跳到函数最后退出,对这种情况Catch住的Exception直接吃掉,因为在Try里面已经做了错误处理。如:

    public Result OutMostFunction()

        {

            Result result = Result.Success;

            try

            {

                try

                {

                    SubFunction1();

                }

                catch (Exception ex)

                {               

                    result = Result.SubFunction_1_Error;              

                    throw ex;

                }

                try

                {

                    SubFunction2();

                }

                catch (Exception ex)

                {

                    result = Result.SubFunction_2_Error;

                    throw ex;

                }

                try

                {

                    SubFunction3();

                }

                catch (Exception ex)

                {

                    result = Result.SubFunction_3_Error;

                    throw ex;

                }

            }

            catch (Exception ex)

            {           

            }

            return result;

        }

    4.       为了区分程序错误与逻辑错误,需要自定义一个Exception类型。比如一个最外层函数调用一个密码验证子函数,就需要区分是因为密码错误(逻辑错误),还是在密码验证过程中程序出现了没有预料到的错误(程序错误)。如:

    public class GoOutException : Exception {}

    public Result OutMostFunction()

        {

            Result result = Result.Success;

            try

            {

                try

                {

                    if (!VerifyPassword(password))

                    {

                        result = Result.Invalid_Password;

                        throw new GoOutException();

                    }

                }

                catch (Exception ex)

                {

                    if (!(ex is GoOutException))

                    {                   

                        result = Result.General_Error;                   

                    }

                    throw ex;

                }           

            }

            catch (Exception ex)

            {           

            }

             return result;

        }

      1. 什么时候使用try catch语句模块,是不是没有明确的答案?  
      2.   
      3. 来自网友的回答:try catch是程序语言本身提供的一种异常处理机制,你大多数写的代码都是要调用底层的api,而这些api的作者在开发api时,很清楚api在使用的过程中会有哪些非正常情况发生,因此他要通知api的调用者,至于对于这种非正常情况怎么处理,就交给了api的调用者。  
      4.   
      5. 你是写代码的,你要调用api,因此你就说api的调用者,你也应该处理api本身存在的非正常情况,那你怎么处理这些非正常状况,这就是你提到的try catch的作用了,它就是干这事的。至于api会有哪些非正常情况发生,需要查api的帮助文档;这些非正常状况怎么处理,这又取决于问题逻辑了,跟实际需求有关系。  
      6. try{A程序块} catch{Exception e}{B程序块} 。。。。。  
      7.   
      8. A程序块比较有可能会出错的地方,B则是如果A中有了错误,进行的处理。就好比,一个流水线上,如果有个地方有个产品堵住了不通了,如果没人处理,则整个流水线就没法动作了,要想保证整个流水线的运作则要有人把这个产品给处理了。try语句就是对A程序块的语句进行捕捉有可能出错的地方,相当于流水线上那个检查的人,catch语句则是处理的.  
      9.   
      10. 什么情况下需要用try-catch呢,那就是不使用这种try结构时,代码报错退出就无法继续执行。有的代码出错就应该退出,有的出错尚可以补救,就不应该退出。对于这种出错不应该退出的就需要使用这种结构,在catch中进行补救。例如,写入一个日志文件,如果这个日志文件被锁定或者占用,那么写入就会出错退出,但是我们并不想看到这样的情况,我们完全可以换一个名字再写入。  
      11.   
      12. 有的函数或者功能调用之后不会出错退出,但是会返回错误码,这个时候也不需要使用try-catch结构。直接根据不同的错误码进行分类处理就行了。  
      13. 所以不是trycatch使用量的问题,还是看应用场景,如果确实需要防止异常退出,需要多次补救,那么再多都是不为过的。  
      14. 还有一个情况要注意,try-catch不是能够解决所有的出错退出,例如php中的segment fault,也就是熟知的段错误,就算是try-catch了也还是会退出,这个时候需要使用gdb进行调试解决了。  
      15.   
      16. try catch后是不是一定要输出异常信息?或者有没有更好的办法去处理日志信息呢?                                                                                    
      17. 如果每一段程序都try catch后输出日志,会导致日志信息臃肿不堪,无法从日志中读取有用的信息,使得解决问题更加困难。那有没有统一处理日志信息的工具包呢!规划好日志信息,异常信息将更加清晰明了,同时多读日志可以不段优化程序减少异常的发生情况,一举多得何乐而不为!  
      18.   
      19. LOG4J学习  
      20. 定义:Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。  
      21. 程序开发环境中的日志记录是由嵌入在程序中以输出一些对开发人员有用信息的语句所组成。例如,跟踪语句(trace),结构转储和常见的 System.out.println或printf调试语句。log4j提供分级方法在程序中嵌入日志记录语句。日志信息具有多种输出格式和多个输出级别。  
      22. 使用一个专门的日志记录包,可以减轻对成千上万的System.out.println语句的维护成本,因为日志记录可以通过配置脚本在运行时得以控制。 log4j维护嵌入在程序代码中的日志记录语句。通过规范日志记录的处理过程,一些人认为应该鼓励更多的使用日志记录并且获得更高程度的效率。  
      23.   
      24. 使用log4j大概涉及3个主要概念:  
      25. 公共类 Logger Logger 负责处理日志记录的大部分操作。  
      26. 公共接口 Appender Appender 负责控制日志记录操作的输出。  
      27. 公共抽象类Layout Layout 负责格式化Appender的输出。
  • 相关阅读:
    vuex
    JS判断浏览器类型和详细区分IE各版本浏览器
    javascript json对象操作(基本增删改查)
    react 使用antd 按需加载
    vue-cli 3.0 豆瓣api接口使用element做分页
    vue-cli 3.0 使用axios配置跨域访问豆瓣接口
    es6之扩展运算符 三个点(...)
    Vue.js——十分钟入门Vuex
    js数组的处理使用
    如何发布自己模块到NPM
  • 原文地址:https://www.cnblogs.com/BearLee/p/11010239.html
Copyright © 2011-2022 走看看