mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-11-04 06:37:55 +08:00 
			
		
		
		
	Merge pull request #13217 from yiisoft/throwable
Catch `\Throwable` in critical places
This commit is contained in:
		@ -636,9 +636,16 @@ try {
 | 
				
			|||||||
} catch(\Exception $e) {
 | 
					} catch(\Exception $e) {
 | 
				
			||||||
    $transaction->rollBack();
 | 
					    $transaction->rollBack();
 | 
				
			||||||
    throw $e;
 | 
					    throw $e;
 | 
				
			||||||
 | 
					} catch(\Throwable $e) {
 | 
				
			||||||
 | 
					    $transaction->rollBack();
 | 
				
			||||||
 | 
					    throw $e;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> Note: in the above code we have two catch-blocks for compatibility 
 | 
				
			||||||
 | 
					> with PHP 5.x and PHP 7.x. `\Exception` implements the [`\Throwable` interface](http://php.net/manual/en/class.throwable.php)
 | 
				
			||||||
 | 
					> since PHP 7.0, so you can skip the part with `\Exception` if your app uses only PHP 7.0 and higher.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The second way is to list the DB operations that require transactional support in the [[yii\db\ActiveRecord::transactions()]]
 | 
					The second way is to list the DB operations that require transactional support in the [[yii\db\ActiveRecord::transactions()]]
 | 
				
			||||||
method. For example,
 | 
					method. For example,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -328,18 +328,17 @@ The above code is equivalent to the following, which gives you more control abou
 | 
				
			|||||||
```php
 | 
					```php
 | 
				
			||||||
$db = Yii::$app->db;
 | 
					$db = Yii::$app->db;
 | 
				
			||||||
$transaction = $db->beginTransaction();
 | 
					$transaction = $db->beginTransaction();
 | 
				
			||||||
 | 
					 | 
				
			||||||
try {
 | 
					try {
 | 
				
			||||||
    $db->createCommand($sql1)->execute();
 | 
					    $db->createCommand($sql1)->execute();
 | 
				
			||||||
    $db->createCommand($sql2)->execute();
 | 
					    $db->createCommand($sql2)->execute();
 | 
				
			||||||
    // ... executing other SQL statements ...
 | 
					    // ... executing other SQL statements ...
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    $transaction->commit();
 | 
					    $transaction->commit();
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
} catch(\Exception $e) {
 | 
					} catch(\Exception $e) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    $transaction->rollBack();
 | 
					    $transaction->rollBack();
 | 
				
			||||||
    
 | 
					    throw $e;
 | 
				
			||||||
 | 
					} catch(\Throwable $e) {
 | 
				
			||||||
 | 
					    $transaction->rollBack();
 | 
				
			||||||
    throw $e;
 | 
					    throw $e;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
@ -352,6 +351,10 @@ will be triggered and caught, the [[yii\db\Transaction::rollBack()|rollBack()]]
 | 
				
			|||||||
the changes made by the queries prior to that failed query in the transaction. `throw $e` will then re-throw the
 | 
					the changes made by the queries prior to that failed query in the transaction. `throw $e` will then re-throw the
 | 
				
			||||||
exception as if we had not caught it, so the normal error handling process will take care of it.
 | 
					exception as if we had not caught it, so the normal error handling process will take care of it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> Note: in the above code we have two catch-blocks for compatibility 
 | 
				
			||||||
 | 
					> with PHP 5.x and PHP 7.x. `\Exception` implements the [`\Throwable` interface](http://php.net/manual/en/class.throwable.php)
 | 
				
			||||||
 | 
					> since PHP 7.0, so you can skip the part with `\Exception` if your app uses only PHP 7.0 and higher.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Specifying Isolation Levels <span id="specifying-isolation-levels"></span>
 | 
					### Specifying Isolation Levels <span id="specifying-isolation-levels"></span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -424,12 +427,18 @@ try {
 | 
				
			|||||||
    } catch (\Exception $e) {
 | 
					    } catch (\Exception $e) {
 | 
				
			||||||
        $innerTransaction->rollBack();
 | 
					        $innerTransaction->rollBack();
 | 
				
			||||||
        throw $e;
 | 
					        throw $e;
 | 
				
			||||||
 | 
					    } catch (\Throwable $e) {
 | 
				
			||||||
 | 
					        $innerTransaction->rollBack();
 | 
				
			||||||
 | 
					        throw $e;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $outerTransaction->commit();
 | 
					    $outerTransaction->commit();
 | 
				
			||||||
} catch (\Exception $e) {
 | 
					} catch (\Exception $e) {
 | 
				
			||||||
    $outerTransaction->rollBack();
 | 
					    $outerTransaction->rollBack();
 | 
				
			||||||
    throw $e;
 | 
					    throw $e;
 | 
				
			||||||
 | 
					} catch (\Throwable $e) {
 | 
				
			||||||
 | 
					    $outerTransaction->rollBack();
 | 
				
			||||||
 | 
					    throw $e;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -573,6 +582,9 @@ try {
 | 
				
			|||||||
} catch(\Exception $e) {
 | 
					} catch(\Exception $e) {
 | 
				
			||||||
    $transaction->rollBack();
 | 
					    $transaction->rollBack();
 | 
				
			||||||
    throw $e;
 | 
					    throw $e;
 | 
				
			||||||
 | 
					} catch(\Throwable $e) {
 | 
				
			||||||
 | 
					    $transaction->rollBack();
 | 
				
			||||||
 | 
					    throw $e;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -59,7 +59,7 @@ Yii Framework 2 Change Log
 | 
				
			|||||||
- Enh #12145: Added `beforeCacheResponse` and `afterRestoreResponse` to `yii\filters\PageCache` to be more easily extendable (sergeymakinen)
 | 
					- Enh #12145: Added `beforeCacheResponse` and `afterRestoreResponse` to `yii\filters\PageCache` to be more easily extendable (sergeymakinen)
 | 
				
			||||||
- Enh #12390: Avoid creating queries with false where condition (`0=1`) when fetching relational data (klimov-paul)
 | 
					- Enh #12390: Avoid creating queries with false where condition (`0=1`) when fetching relational data (klimov-paul)
 | 
				
			||||||
- Enh #12399: Added `ActiveField::addAriaAttributes` property for `aria-required` and `aria-invalid` attributes rendering (Oxyaction, samdark)
 | 
					- Enh #12399: Added `ActiveField::addAriaAttributes` property for `aria-required` and `aria-invalid` attributes rendering (Oxyaction, samdark)
 | 
				
			||||||
- Enh #12619: Added catch `Throwable` in `yii\base\ErrorHandler::handleException()` (rob006)
 | 
					- Enh #12619: Added catch `Throwable` in `yii\base\ErrorHandler::handleException()`, transactions and simlar places where consistency must be kept after exception (rob006, cebe)
 | 
				
			||||||
- Enh #12659: Suggest alternatives when console command was not found (mdmunir, cebe)
 | 
					- Enh #12659: Suggest alternatives when console command was not found (mdmunir, cebe)
 | 
				
			||||||
- Enh #12726: `yii\base\Application::$version` converted to `yii\base\Module::$version` virtual property, allowing to specify version as a PHP callback (klimov-paul)
 | 
					- Enh #12726: `yii\base\Application::$version` converted to `yii\base\Module::$version` virtual property, allowing to specify version as a PHP callback (klimov-paul)
 | 
				
			||||||
- Enh #12732: Added `is_dir()` validation to `yii\helpers\BaseFileHelper::findFiles()` method (zalatov, silverfire)
 | 
					- Enh #12732: Added `is_dir()` validation to `yii\helpers\BaseFileHelper::findFiles()` method (zalatov, silverfire)
 | 
				
			||||||
 | 
				
			|||||||
@ -439,6 +439,9 @@ class ActiveRecord extends BaseActiveRecord
 | 
				
			|||||||
        } catch (\Exception $e) {
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
            $transaction->rollBack();
 | 
					            $transaction->rollBack();
 | 
				
			||||||
            throw $e;
 | 
					            throw $e;
 | 
				
			||||||
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
 | 
					            $transaction->rollBack();
 | 
				
			||||||
 | 
					            throw $e;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -545,6 +548,9 @@ class ActiveRecord extends BaseActiveRecord
 | 
				
			|||||||
        } catch (\Exception $e) {
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
            $transaction->rollBack();
 | 
					            $transaction->rollBack();
 | 
				
			||||||
            throw $e;
 | 
					            throw $e;
 | 
				
			||||||
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
 | 
					            $transaction->rollBack();
 | 
				
			||||||
 | 
					            throw $e;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -585,6 +591,9 @@ class ActiveRecord extends BaseActiveRecord
 | 
				
			|||||||
        } catch (\Exception $e) {
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
            $transaction->rollBack();
 | 
					            $transaction->rollBack();
 | 
				
			||||||
            throw $e;
 | 
					            throw $e;
 | 
				
			||||||
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
 | 
					            $transaction->rollBack();
 | 
				
			||||||
 | 
					            throw $e;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -420,7 +420,7 @@ class Connection extends Component
 | 
				
			|||||||
     * Use 0 to indicate that the cached data will never expire.
 | 
					     * Use 0 to indicate that the cached data will never expire.
 | 
				
			||||||
     * @param \yii\caching\Dependency $dependency the cache dependency associated with the cached query results.
 | 
					     * @param \yii\caching\Dependency $dependency the cache dependency associated with the cached query results.
 | 
				
			||||||
     * @return mixed the return result of the callable
 | 
					     * @return mixed the return result of the callable
 | 
				
			||||||
     * @throws \Exception if there is any exception during query
 | 
					     * @throws \Exception|\Throwable if there is any exception during query
 | 
				
			||||||
     * @see enableQueryCache
 | 
					     * @see enableQueryCache
 | 
				
			||||||
     * @see queryCache
 | 
					     * @see queryCache
 | 
				
			||||||
     * @see noCache()
 | 
					     * @see noCache()
 | 
				
			||||||
@ -435,6 +435,9 @@ class Connection extends Component
 | 
				
			|||||||
        } catch (\Exception $e) {
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
            array_pop($this->_queryCacheInfo);
 | 
					            array_pop($this->_queryCacheInfo);
 | 
				
			||||||
            throw $e;
 | 
					            throw $e;
 | 
				
			||||||
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
 | 
					            array_pop($this->_queryCacheInfo);
 | 
				
			||||||
 | 
					            throw $e;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -457,7 +460,7 @@ class Connection extends Component
 | 
				
			|||||||
     * @param callable $callable a PHP callable that contains DB queries which should not use query cache.
 | 
					     * @param callable $callable a PHP callable that contains DB queries which should not use query cache.
 | 
				
			||||||
     * The signature of the callable is `function (Connection $db)`.
 | 
					     * The signature of the callable is `function (Connection $db)`.
 | 
				
			||||||
     * @return mixed the return result of the callable
 | 
					     * @return mixed the return result of the callable
 | 
				
			||||||
     * @throws \Exception if there is any exception during query
 | 
					     * @throws \Exception|\Throwable if there is any exception during query
 | 
				
			||||||
     * @see enableQueryCache
 | 
					     * @see enableQueryCache
 | 
				
			||||||
     * @see queryCache
 | 
					     * @see queryCache
 | 
				
			||||||
     * @see cache()
 | 
					     * @see cache()
 | 
				
			||||||
@ -472,6 +475,9 @@ class Connection extends Component
 | 
				
			|||||||
        } catch (\Exception $e) {
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
            array_pop($this->_queryCacheInfo);
 | 
					            array_pop($this->_queryCacheInfo);
 | 
				
			||||||
            throw $e;
 | 
					            throw $e;
 | 
				
			||||||
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
 | 
					            array_pop($this->_queryCacheInfo);
 | 
				
			||||||
 | 
					            throw $e;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -671,7 +677,7 @@ class Connection extends Component
 | 
				
			|||||||
     * @param callable $callback a valid PHP callback that performs the job. Accepts connection instance as parameter.
 | 
					     * @param callable $callback a valid PHP callback that performs the job. Accepts connection instance as parameter.
 | 
				
			||||||
     * @param string|null $isolationLevel The isolation level to use for this transaction.
 | 
					     * @param string|null $isolationLevel The isolation level to use for this transaction.
 | 
				
			||||||
     * See [[Transaction::begin()]] for details.
 | 
					     * See [[Transaction::begin()]] for details.
 | 
				
			||||||
     * @throws \Exception
 | 
					     * @throws \Exception|\Throwable if there is any exception during query. In this case the transaction will be rolled back.
 | 
				
			||||||
     * @return mixed result of callback function
 | 
					     * @return mixed result of callback function
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function transaction(callable $callback, $isolationLevel = null)
 | 
					    public function transaction(callable $callback, $isolationLevel = null)
 | 
				
			||||||
@ -689,6 +695,11 @@ class Connection extends Component
 | 
				
			|||||||
                $transaction->rollBack();
 | 
					                $transaction->rollBack();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            throw $e;
 | 
					            throw $e;
 | 
				
			||||||
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
 | 
					            if ($transaction->isActive && $transaction->level === $level) {
 | 
				
			||||||
 | 
					                $transaction->rollBack();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            throw $e;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $result;
 | 
					        return $result;
 | 
				
			||||||
 | 
				
			|||||||
@ -95,15 +95,16 @@ class Migration extends Component implements MigrationInterface
 | 
				
			|||||||
        try {
 | 
					        try {
 | 
				
			||||||
            if ($this->safeUp() === false) {
 | 
					            if ($this->safeUp() === false) {
 | 
				
			||||||
                $transaction->rollBack();
 | 
					                $transaction->rollBack();
 | 
				
			||||||
 | 
					 | 
				
			||||||
                return false;
 | 
					                return false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            $transaction->commit();
 | 
					            $transaction->commit();
 | 
				
			||||||
        } catch (\Exception $e) {
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
            echo 'Exception: ' . $e->getMessage() . ' (' . $e->getFile() . ':' . $e->getLine() . ")\n";
 | 
					            $this->printException($e);
 | 
				
			||||||
            echo $e->getTraceAsString() . "\n";
 | 
					            $transaction->rollBack();
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
 | 
					            $this->printException($e);
 | 
				
			||||||
            $transaction->rollBack();
 | 
					            $transaction->rollBack();
 | 
				
			||||||
 | 
					 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -123,21 +124,31 @@ class Migration extends Component implements MigrationInterface
 | 
				
			|||||||
        try {
 | 
					        try {
 | 
				
			||||||
            if ($this->safeDown() === false) {
 | 
					            if ($this->safeDown() === false) {
 | 
				
			||||||
                $transaction->rollBack();
 | 
					                $transaction->rollBack();
 | 
				
			||||||
 | 
					 | 
				
			||||||
                return false;
 | 
					                return false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            $transaction->commit();
 | 
					            $transaction->commit();
 | 
				
			||||||
        } catch (\Exception $e) {
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
            echo 'Exception: ' . $e->getMessage() . ' (' . $e->getFile() . ':' . $e->getLine() . ")\n";
 | 
					            $this->printException($e);
 | 
				
			||||||
            echo $e->getTraceAsString() . "\n";
 | 
					            $transaction->rollBack();
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
 | 
					            $this->printException($e);
 | 
				
			||||||
            $transaction->rollBack();
 | 
					            $transaction->rollBack();
 | 
				
			||||||
 | 
					 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return null;
 | 
					        return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param \Throwable|\Exception $e
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function printException($e)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        echo 'Exception: ' . $e->getMessage() . ' (' . $e->getFile() . ':' . $e->getLine() . ")\n";
 | 
				
			||||||
 | 
					        echo $e->getTraceAsString() . "\n";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * This method contains the logic to be executed when applying this migration.
 | 
					     * This method contains the logic to be executed when applying this migration.
 | 
				
			||||||
     * This method differs from [[up()]] in that the DB logic implemented here will
 | 
					     * This method differs from [[up()]] in that the DB logic implemented here will
 | 
				
			||||||
 | 
				
			|||||||
@ -28,9 +28,16 @@ use yii\base\InvalidConfigException;
 | 
				
			|||||||
 * } catch (\Exception $e) {
 | 
					 * } catch (\Exception $e) {
 | 
				
			||||||
 *     $transaction->rollBack();
 | 
					 *     $transaction->rollBack();
 | 
				
			||||||
 *     throw $e;
 | 
					 *     throw $e;
 | 
				
			||||||
 | 
					 * } catch (\Throwable $e) {
 | 
				
			||||||
 | 
					 *     $transaction->rollBack();
 | 
				
			||||||
 | 
					 *     throw $e;
 | 
				
			||||||
 * }
 | 
					 * }
 | 
				
			||||||
 * ```
 | 
					 * ```
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * > Note: in the above code we have two catch-blocks for compatibility
 | 
				
			||||||
 | 
					 * > with PHP 5.x and PHP 7.x. `\Exception` implements the [`\Throwable` interface](http://php.net/manual/en/class.throwable.php)
 | 
				
			||||||
 | 
					 * > since PHP 7.0, so you can skip the part with `\Exception` if your app uses only PHP 7.0 and higher.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * @property bool $isActive Whether this transaction is active. Only an active transaction can [[commit()]]
 | 
					 * @property bool $isActive Whether this transaction is active. Only an active transaction can [[commit()]]
 | 
				
			||||||
 * or [[rollBack()]]. This property is read-only.
 | 
					 * or [[rollBack()]]. This property is read-only.
 | 
				
			||||||
 * @property string $isolationLevel The transaction isolation level to use for this transaction. This can be
 | 
					 * @property string $isolationLevel The transaction isolation level to use for this transaction. This can be
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user