关于错误和异常的一些理解
在开发过程中,错误、异常的暴露及处理不可避免。
合理地暴露错误和抛出异常,是提升开发效率的一大法门。
潜在的问题对应的修正成本,会随着项目的迭代不断上升;因此,尽早暴露问题,尽早解决问题,是对整个工程的负责。那么在开发过程中,如何尽早的暴露问题,并解决?暴露问题后速度迅速的定位问题,并修正?生产环境中又该作哪些处理?
- 采用严格模式。暴露包括
warning
级别在内的问题,使代码更加规范。 - 使用断言。提前对变量/数据进行有效性要求,及时抛出错误;也可避免应用层永无止境的合法性判断需求。
- 格式化的错误信息和统一化的错误处理通道。原始的错误信息,对开发人员来说,有时候未必友好。如在Web中阅读原始错误信息可能不便,需要对其加上相应的HTML标签;在客户端限定返回数据为json格式时,裸信息会被视为非法数据,因此也需要格式化。
- 开发模式下,应该尽可能地往简洁有效(即不要带上无关信息)/详细(该有的信息量一定要有)/可读性强(友好阅读,一目了然)三个方面因地制宜地去格式化。
- 生产环境下,同理,要返回普通用户可读的错误信息。
在 PHP 中,「错误」和「异常」存在一些区别。
「错误」可以看做是无意的、被动的行为,如代码中出现了 a = 1 / 0;
这类使开发/运行环境无法编译/解释的语句,就会报出一个错误。
「异常」可以理解为是开发者主动抛出的。比如在程序中,判断用户登录状态,如果 token 过期,就在其条件分支处主动抛一个 token 过期
的异常。
某个请求中,出现错误和异常,可能会直接回显(如果开启了相应配置),这么一来可能会影响返回数据格式的合法性。因此,科学地进行调试,需要做到几点:
- 统一的请求出口。出口中包含对异常的捕捉,保证所有的请求,即使发生错误,也一定要返回值,返回格式是合法的。
- 让错误的抛出可控。因为错误并非主动抛出,开发者无法预知何处会出现错误;所以在这里可以通过
set_error_handler
方法,对错误做统一的处理,如在方法中抛出异常(异常中要包含错误相关的信息量)。 - 异常是主动抛出的,可直接在应用层中 catch;也可以通过
set_exception_handler
方法,对它进行统一处理。 - 其实以上两点,只有一个目的:就是在一个请求中,只在规定的地方回显字符,避免因错误/异常的被动回显,保证返回数据格式的正确性。
error_reporting() 范例
1 | <?php |
1 | ini_set('error_log','/dev/null'); |
实践使用待整理……