Yii Framework Forum

yii2 tratamento de exceções de banco


(Rudinei Dias) #1

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?


(Fosales) #2

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();

        }

    },