简体   繁体   English

如何设计代码而无需重复捕获MVC框架中的错误?

[英]How to design code without repetitions to catch errors in mvc framework?

Let's suppose there is model that performs some logic on saving object. 假设有一个模型对保存对象执行一些逻辑。 This logic consists of db-transactions, some external services calls. 此逻辑由db事务和一些外部服务调用组成。

class ExampleModel {
  //some field
  //constructor and getters with setters

  public function save() {
    $db->beginTransaction();
    $db->somequery();
    $db->anotherone();
    $object->externalApiCall();
    $object->saveToCache();
  }


}

My question is what is the best way to catch errors and make rollbacks? 我的问题是捕获错误并进行回滚的最佳方法是什么?

Solution#1 Catch everything in the model, rollback there, log some information and re-throw error to a controller. 解决方案#1捕获模型中的所有内容,在其中回滚,记录一些信息,然后将错误重新抛出给控制器。 Will look something like this: 看起来像这样:

class ExampleModel {
  //some field
  //constructor and getters with setters

  public function save() {
    try {
     $db->beginTransaction();
     $db->somequery();
     $db->anotherone();
     $object->externalApiCall();
     $object->saveToCache();
    } catch (DbException $e) {
      $db->rollback();
      $logger->log($e->getMessage());
      throw $e
    }
     catch (ApiExcetpion $e) {
       somelogic();
       throw $e;
     }
  }


}

My main concern with this approach is that there is a lot of redundancy in writing try/catch blocks. 我对这种方法的主要担心是在编写try / catch块时有很多冗余。 For every composite method there will be try catch block. 对于每种复合方法,都会有try catch块。

Solution #2 Throw errors in a Model, and handle rollbacks/logging etc in a controller. 解决方案#2在模型中引发错误,并在控制器中处理回滚/记录等。 This one I don't like because it breaks MVC pattern, and a controller becomes fat. 我不喜欢这个,因为它破坏了MVC模式,并且控制器变胖了。

Solution #3 Binding error-listeners to an app instance so that they will handle exceptions according to their logic. 解决方案3将错误侦听器绑定到应用程序实例,以便它们将根据其逻辑处理异常。 Example: 例:

class ExampleModel {
  //some field
  //constructor and getters with setters

  public function save() {
    $db->beginTransaction();
    $db->somequery();
    $db->anotherone();
    $object->externalApiCall();
    $object->saveToCache();
  }


}

$app->bind_error_handler("DbTransactionException", function () {
     rollback();
     log();
     return View::render("some error");
});

I overall like this approach because there are no numerous try/catch blocks. 我总体上喜欢这种方法,因为没有很多try / catch块。 Controller is skinny and error logic is de-coupled from everything else. 控制器很瘦,错误逻辑与其他所有逻辑都解耦了。 My concern with last approach is whether or not it is considered best practice. 我对最后一种方法的关注是,是否将其视为最佳实践。 Also is this approach flexible and will it give me flexibility of a first approach? 这种方法是否也很灵活,是否会给我第一个方法的灵活性?

Overall question: What is considered best practice in handling errors (transactional and other) in MVC world? 总体问题:在MVC世界中,处理错误(事务性错误和其他错误)的最佳实践是什么? And which solution from what I have provided is the best one? 我提供的哪种解决方案是最好的?

Use an ORM (like Doctrine) and let the Unit Of Work take care of transactions handling. 使用ORM(如“学说”),让工作单元负责事务处理。

All the INSERT / UPDATE / DELETE operations are queued until you invoke YOUR_ORM::flush . 所有INSERT / UPDATE / DELETE操作都排队,直到您调用YOUR_ORM::flush为止。 When an exception occurs the transaction is automatically rolled back. 发生异常时,事务将自动回滚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM