yii2 tratamento de exceções de banco

Olá.

[size=2]Meu problema inicial é com exclusão de registros com dependentes (que possuem filhos) e estoura um erro de constraint na tela.[/size]

Já fiz pesquisa por alguns dias, não encontrei nada que funcionasse no yii2, tem algumas soluções para yii1 mas não funcionaram no 2.

Gostaria de saber dos veteranos como fazem o tratamento de exceções de banco para não desviar para aquela página de erro genérica no YII2.

Fiz umas modificações, mas não ficou elegante.

Tabela Ambientes 1 - N [size=2]Tabela [/size][size=2]SapAmbientes[/size]

Tenho uma classe model chamado Ambientes

onde coloquei

public function beforeDelete()


{

[size=2] $p = new \app\models\SapPerfis(); //descomente a classe que precisa para verificar registros dependentes[/size]

    \Yii::$app->getSession()->remove('deleteAmbientes');


    $retorno = $p::find()->where(['ambiente' => $this->ambiente])->one();


    if ($retorno!==null){


        \Yii::$app->getSession()->setFlash('deleteAmbientes', Yii::t('app', 'Can\'t delete this record. There are some dependents records.'));


        return FALSE;


    }else{


        return TRUE;


    }


}  

no controller modifiquei o actionDelete

public function actionDelete($id)


{


	if (!Yii::$app->user->can('deleteAmbientes'))


		throw new ForbiddenHttpException;


		


    $record = $this->findModel($id); 


    //$this->findModel($id)->delete();


    if ($record !== null) { 


       try { 


          $ret = $record->delete(); 


          if ($ret===FALSE){ 


              if (\Yii::$app->getSession()->hasFlash('deleteAmbientes')){ 


                   return $this->render('view', [ 


                       'model' => $this->findModel($id), 


                   ]); 


              } 


          } 


          return $this->redirect(['index']); 


       } catch (\ErrorException $e) { 


           //throw new \yii\base\Exception("O registro não pode ser exluído"); 


          Yii::warning("O registro não pode ser exluído."); 


          return $this->redirect(['index']); 


       } 


    } 





    return $this->redirect(['index']);


}

e na view coloquei

    <?=(\Yii::$app->getSession()->hasFlash('deleteAmbientes')?


        '<div class="alert-danger"><p class="error-summary">'


        .\Yii::$app->getSession()->getFlash('deleteAmbientes')


        .' (<a href="javascript:history.back(-1)" class="backLink">'


        .Yii::t('app', 'Return previous page')


        .')</a></p></div>'


        :''


    )?>

Por enquanto funciona, mas tenho que programar as validações, ao invés de apenas redirecionar um erro do banco de dados.

Como vocês fazem para tal tratamento?

Olá Rudinei,

Para fins de registro para as demais pessoas que tiverem a mesma necessidade, estou postando a resposta do yii-framework-brasil@googlegroups.com. Este código deve ser inserido no arquivo web.php:




 'on afterAction' => function ($event) {

        $exception = Yii::$app->errorHandler->exception;

        if ($exception instanceof \yii\db\IntegrityException) {

            $event->handled = true;

            Yii::$app->getSession()->setFlash('danger', 'Este registro é referenciado e não pode ser excluído.');

            return Yii::$app->getResponse()->redirect(Yii::$app->request->referrer)->send();

        }

    },