RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 848727
Accepted
Roman Andreev
Roman Andreev
Asked:2020-07-01 04:47:50 +0000 UTC2020-07-01 04:47:50 +0000 UTC 2020-07-01 04:47:50 +0000 UTC

创建我们自己的异常类来捕获各种错误是一种好习惯吗?

  • 772

我最近刚刚学习了异常的机制,现在我正在掌握它们。这里有几个关于它们使用的问题:

是否可以创建自己的空 Exception 类继承自 Exception 类,只是为了有一个单独的异常名称?例如:我正在处理文件,如果文件无法加载文件 - 我会抛出异常

 throw new FileException('Не удалось загрузить файл') 

`FileException 类本身不包含任何内容

class FileException extends \Exception
{
    //empty!
}

第二个问题,从第一个问题开始。我这样做是为了捕捉各种错误。例如,在网站上添加消息时,我可能会得到不同的异常,例如:错误消息、上传文件失败、PDO 错误。也就是说,在控制器中它将如下所示:

public function actionMethod()
{
    try {
        //some code;
    } catch (FileException $e) {
        echo 'С файлами что то пошло не так:' . $e->getMessage();
    } catch (MessageException $e) {
        echo 'С сообщением что то пошло не так:' . $e->getMessage();
    } catch (PDOException $e) {
        echo 'С БД что то пошло не так:' . $e->getMessage();
    } catch (Exception $e) {
        echo 'Что то совсем пошло не так :(';
    }
}

有可能这样做吗?控制器有这么多catch是正常的吗?这种做法有多好?或者我误解了异常是如何工作的?

php
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Total Pusher
    2020-07-01T07:31:45Z2020-07-01T07:31:45Z

    您是否需要分别为每个错误提供例外?

    回答问题

    在网站上添加消息时,我会收到不同的异常:消息不正确、上传文件失败、PDO 错误。您是否需要分别为每个错误提供例外?

    您需要从以下方面入手:

    • 这将为用户提供异常文本
    • 会给开发商带来什么

    错误信息

    上传文件失败

    它应该提供给浏览器,以便用户理解他的错误并纠正它。尝试使这样的信息易于理解。“上传文件失败。请使用允许的格式(docx、xlsx)”

    PDO 错误

    用户不需要知道网站的功能。将其写在您的日志中并说“服务器错误,请稍后再试”。也许您看到了来自 Google 和 Yandex 的消息,“有些东西坏了,但我们已经知道了”。

    // глобальный отлов ошибок
    try {
    
      try {
        throw new Exception("DB error");
      } catch (Exception $e) {
        // Я люблю в качестве кодов ошибок использовать 400-е и 500-е HTTP коды
        $errCode = $e->getCode()
        if($errCode >= 500) {
          syslog(LOG_ERR, '[Sign][docs.list][error]MySQL is gone away');
          http_response_code($errCode);
          throw new Exception("Ошибка сервера, попробуйте чуть позже");
        }
      }
    
    } catch (Exception $e) {
      // выводим ошибку пользователю
    }
    

    顺便说一句,您可以写入syslog,PHP 程序员由于某种原因不应该忘记它。如果您将 ELK 之类的内容附加到 syslog,您可以跟踪错误的动态并设置通知。

    如果错误发生在深处的某个地方,那很方便

    如果某个深度嵌套的方法出现问题,那么抛出异常就像紧急冒泡一样。这比在链中向后返回 null/false 要好。你的代码会变得更干净。

    使用异常作为构建逻辑的一种方式,而不是if ... else ...

    例子:

    try {
      // пробуем получить координаты по картам Гугла
      $this->geoPositionGoogle($data);
    } catch (Exception $e) {
      // если не получилось, пробуем по картам Яндекса
      $this->geoPositionYandex($data);
    }
    

    防御性编程

    其本质是检查传入值和期望值。我最常在两种情况下使用:

    • 许多潜在的错误点。我有这个文件的电子签名(网络、数据库、签名脚本等可能会失败)。详细的错误报告使问题诊断更加容易
    • 与外部服务的交互,在程序员不知情的情况下,某些东西可能会发生变化

    与 1C 的交换示例:

    switch($row['SECTION_TYPE']) {
      case 'directionBonus':
        // Ожидается, что название будет начинаться со слова "Бонус"
        if(!preg_match('~^Бонус\s+(.*)$~i', $row['SECTION_NAME'], $m)) throw new Exception("Wrong name");
        break;
      case 'groupDDP';
        // Ожидается, что название будет начинаться с кода раздела
        if(!preg_match('~^([0-9]+\.[0-9]+\.[0-9]+)\s+(.*)$~i', $row['SECTION_NAME'], $m)) throw new Exception("Wrong name");
        break;
      default:
        // Ожидается, что других вариантов нет
        throw new Exception("No such case");
    }
    

    创建我们自己的异常类来捕获各种错误是一种好习惯吗?

    很好,但不要得意忘形。做到最低限度。如果有更多,你会开始感到困惑和挂起,决定哪个异常更合适。

    好文章

    • 4
  2. freim
    2020-07-01T05:31:46Z2020-07-01T05:31:46Z

    原则上,总是有一种绘制异常层次结构的诱惑——它看起来很酷,而且令人赏心悦目。但正如经验所表明的(无论如何,我个人),这是一件相当没有意义的事情。至少引入一个您自己的类是有意义的,因为通常需要将您自己的异常与标准异常区分开来。当您需要向用户提供本地化消息并继续工作时,非致命异常需要另一个类。基本上就是这样,即使对于大型项目,这对也足够了。但总的来说,我建议您保持简单——仅在您认为确实需要时才引入新的异常类。

    还有一件事:捕获所有可能的异常类型 - 这种情况是不正常的,只有在必要时才分离异常。这就是建立层次结构的原因。

    • 3

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5