Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Carcleo

Estrutura Try Catch

Recommended Posts

Bom dia pessoal.

 

Estive lendo sobre a Estrutura Try Catch e, pelo que notei, ela serve para substituir de forma mais profissional e elegante as exibições de erros que, normalmente, são geradas pela condicional IF.

 

Estou certo?

 

Ou seja: Ou se usa IF ou Try Catch. É isso mesmo?

 

Tipo

try
{
}
Catch
{
}

Ou

If
{
}
else
{
]

 

É isso mesmo?

Se for isso, o meu código abaixo esta uma bagunça:

<?php
if(isset($_GET["acao"]) and $_GET["acao"]=="cadastra")
{
  try{
	$select_admin_string="select usuario_admin from admin where usuario_admin = '".$_POST['cad_usuario_admin']."'";

	$select_admin = $conexao->query($select_admin_string);
	if($select_admin->num_rows==0)
	{
	   $cadastro_admin_string="
	   insert into admin (nome_admin, usuario_admin, senha_admin, bloqueio_admin)
	   values(
			   '".$_POST['cad_nome_admin']."', 
			   '".$_POST['cad_usuario_admin']."', 
			   '".$_POST['cad_senha_admin']."', 
			   'n'
			  )
							 ";
	   $cadastro_admin =  $conexao->query($cadastro_admin_string);
	   if($cadastro_admin)						 
	   {
		   echo "<table align=\"center\" width=\"600px\" height=\"300px\"><tr><td align=\"center\" valign=\"middle\">";
		   echo "Cadastro Efetuado com sucesso";
		   echo "<br />";
		   echo "Redirecionando em 10 segundos...";
		   echo "</td></tr></table>";
			   header("refresh: 10; url=admin_cad.php"); 
	   }
	   else
	   {
		   echo "<table align=\"center\" width=\"600px\" height=\"600px\"><tr><td align=\"center\" valign=\"middle\">";
		   echo "Erro no cadastro. Tente novament!";
		   echo "<br />";
		   echo "Redirecionando em 10 segundos...";
		   echo "</td></tr></table>";
			   header("refresh: 10; url=admin_cad.php"); 
	   }
	 }
	 else
	 {
		 echo "<table align=\"center\" width=\"600px\" height=\"300px\"><tr><td align=\"center\" valign=\"middle\">";
		 echo "Este usuário já esta cadastrado, por favor escolha outro";
		 echo "<br />";
	     echo "Redirecionando em 10 segundos...";
		 echo "</td></tr></table>";
		 header("refresh: 10; url=admin_cad.php"); 
	 }

  }catch(Exception $e) 
  {
	  echo $e->getMessage();
  }
}
?>

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não vejo neste sentido. Pelo que entendo, o Try é para tratamento de erros. Apesar que no if/else você PODE fazer, porém ele é uma condicional para fazer algum teste da lógica de seu sistema, é diferente do Try/Catch onde você teste se vai acontecer algum erro.

 

Eu disse que pode fazer tratamento de erro no if, porém eu acho isso uma "gambiarra", dependendo da situação, até por que não é em todo lugar que vai ficar usando try/catch. Posso esar errado, alguém mais experiênte ajuda?

Compartilhar este post


Link para o post
Compartilhar em outros sites

você não consegue tratar um erro com if else

 

você faria o que?

 

if($erro == "ERRO, you have a sintaxe error"){
echo 'Esses dados não podem ser acessados';
}

 

o if else são condições como nosso amigo disse para ajudar na lógica mais não para tratar erro.

 

o try eu vou tentar explicar bem lógico try em inglês é tentar

bom ele vai tentar fazer algo o catch é se não der certo ai você vai lançar uma mensagem pro usuário evitando que mostre erros como: erro de sintaxe, variavel não definida etc...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Primeiramente você precisa entender o conceito de exceção.

ex.ce.ção, [Datação: século XVI]

 

1. ato ou efeito de excetuar

2. o que não se submete à regra

3. desvio da regra geral (comum)

4. privilégio

 

Uma exceção é algo anormal que acontece em seu sistema. Anormal deve ser entendido como "não é esperado que isso ocorra sempre".

 

As exceções em linguagens de programação surgiram da necessidade de possibilitar o tratamento de erros antes que estes chegassem ao usuário através de mensagens na tela.

Esse tipo de controle era feito antigamente com blocos if ... else, entretanto, algo acabava se perdendo. Também não era possível postergar o tratamento desse erro para uma camada superior (o que dizem ser desaconselhável, mas muitas vezes, é necessário).

 

Além disso, uma exceção traz algumas informações agregadas, tal como o código, a linha, o arquivo e uma pilha de execução.

 

É importante que em um bloco try ... catch haja apenas o código crítico, sujeito a erros, e algumas dependências, não o código todo.

Além disso, você precisa estar ciente de que TODO o código posterior à chamada que gerou a exceção não será executado.

 

Nesse ponto, os blocos diferem. Por exempo:

Imagine que você precisa executar 2 funções, tal que a segunda depende da primeira.

 

Com if ... else:

condicao = algumafuncao();
if(condicao é válida) then
facaalgo();
else
trateoerro();
endif;

outrafuncao(); // será executado mesmo que a chamada de "algumafuncao" falhe

 

Com o bloco try... catch:

try
algumafuncao();  // lança uma exceção
facaalgo(); // Nada a partir daqui será executado
outrafuncao();
catch excecao
trateoerro();

 

Aí você fala:

- Ah, eu poderia mover a chamada de outrafuncao para dentro do bloco if.

 

Nesse caso, pode, mas e se fossem 3 funções que dependessem uma da outra?

Tente fazer com if ... else, se você conseguir fazer essa dependência sem criar um outro bloco if ... else eu mudo de nome.

 

Com try ... catch eu mantenho essa dependência linearmente:

try
funcao1();
funcao2();
funcao3();
catch excecao
trataroerro();

Se 1 lançar exceção, nem 2 nem 3 são executadas. Se 2 lançar, 3 não é executada e assim por diante.

Compartilhar este post


Link para o post
Compartilhar em outros sites
você não consegue tratar um erro com if else

Acredito que sim, veja:

 

<?
  if(error()){
     die();
  }
?>

Apesar de que, o die() vai parar o script, caso entre nesta condicional.

Se eu tiver errado me corrija, quero entender melhor! :thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites

O if pode até funcionar para erros do PHP/sistema, mas para erros lançados pelo usuário será bem mais fácil/adequado trabalhar com try...catch.

Compartilhar este post


Link para o post
Compartilhar em outros sites

você consegue esconder os erros com o @ frente as funções..

 

lembrando que o @ só pode ser usado somente em expressões.

 

até onde meus mínimos conhecimentos me permitem com o if else não é possível tratar o erro de fato, mais eu posso ter me equivocado no comentário sim.

 

o que melhor quis dizer é que tratar um erro de fato com if else não é possível pois ele vai trabalhar como você fez algo se retorna tal valor ele vai mostrar uma mensagem.

 

já o try catch ele vai ler todas as ações por exemplo uma inserção de dados depois que ele ler tudo se não tiver nenhum erro ele continua se não o catch lança uma nova exceção.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom usa os 2 em conjuto e melhor ainda kkkk

 

trabalhando com try cacth e throw!!

 

fica algo assim!

 

 
       if (!isset($this->var))
           throw new ErrorException('Houve um erro na execução. Tente novamente');

no inicializador do sua aplicação!
try {           
           //init da aplicação

       } catch (Exception $erro) {
           echo json_encode(array('msg' => $erro->getMessage(), 'response' => false));
$this->logError($erro->getMessage());
       }

 

todo throw é lançado pro bloco try ! torna muito facil faze um log de erros dessa forma!

em uma aplicação seguindo MVC por exemplo (bootstrap), você tem so 1 bloco try catch pra todo o sistema, apenas recebendo os throw's!

Compartilhar este post


Link para o post
Compartilhar em outros sites
você consegue esconder os erros com o @ frente as funções..

Isso PRA mim se chamada gambiarra. Só pra brincar, fui obrigado a criar essa funçãozinha! kkkk

 

<?
function getGambiarra($string){
    $getArroba = substr($string, 0);
    $i = 0;
    while($getArroba[0] == '@'):
         echo 'Seu pog! ' , PHP_EOL;
         $i++;
         if($i == 10):
             exit;
          endif;
    endwhile;
}
?>

Compartilhar este post


Link para o post
Compartilhar em outros sites

Try-Catch trabalha sem interferir no fluxo. Dizer que é "mais profissional" ou que é "um substituto ao IF" são equívocos.

 

Cada um tem seu lugar e ocasião corretas para uso.

 

Um bloco IF-ELSE está presente no fluxo do programa, faz parte do seu algoritmo, uma exceção, como o próprio nome já diz é reservada para algo imprevisto.

 

Ainda, o lançamento de uma exceção - quase sempre - consiste em uma verificação prévia através de IF.

 

O tratamento de erros é melhor operado com try-catch, como já mencionado pelo Henrique, devido à pilha de execução.

 

Quando trabalhamos com funções, sempre conhecemos seu retorno. Se isso não é verdadeiro, há um problema de arquitetura do sistema.

 

Uma vez que o retorno é conhecido, precisamos de um escape para comportamentos inesperados:

 

FUNÇÃO: DIVISÃO ( NÚMERO: DIVIDENDO, NÚMERO: DIVISOR ) -> NÚMERO: QUOCIENTE

 

Temos que, uma função, chamada divisão recebe dois argumentos:

- Um numeral, chamado dividendo

- Um numeral, chamado divisor

 

E retorna um numeral.

 

Porém, como todos sabemos, a divisão possui uma exceção: quando o divisor é zero.

 

A primeira solução que poderíamos tomar é alterar o formato de retorno da função para devolver um mapa, oferecendo um identificador de erros e/ou o resultado:

 

FUNÇÃO: DIVISÃO ( NÚMERO: DIVIDENDO, NÚMERO: DIVISOR ) -> LISTA: [ INTEIRO: COD_ERRO, NÚMERO: QUOCIENTE ] 

 

Percebe que, seguindo este raciocínio, TODAS as funções existentes no planeta </hipérbole> deveriam oferecer esse tipo de retorno?

 

Com algum raciocínio, observamos que esse comportamento é, obviamente, incorreto. Deve haver alguma outra forma da função lançar erros.

 

FUNÇÃO: DIVISÃO ( NÚMERO: DIVIDENDO, NÚMERO: DIVISOR ) -> NÚMERO: QUOCIENTE
   SE DIVISOR NÃO É 0 ENTÃO RETORNE DIVIDENDO / DIVISOR
   LANCE ERRO "NÃO É POSSÍVEL DIVIDIR POR ZERO!"
   FIM FUNÇÃO

 

Para interromper o fluxo e impedir que falhas posteriores consequentes desta aconteçam, seria necessário lançar um erro fatal. Qualquer outro erro que prossiga com o fluxo acarretará em erros em série

 

NÚMERO: QUANTIDADE_ATUAL = 50
NÚMERO: QUANTIDADE_TOTAL = 0
NÚMERO: PERCENTAGEM = DIVISÃO ( QUANTIDADE_ATUAL, QUANTIDADE_TOTAL ) * 100 // Erro: Multiplicação de NULO por 100

 

Observamos que esta também não é a técnica mais adequada para tratamento de erros. Catch oferece uma alternativa para pegar - a tradução literal de "catch" - e retornar ao fluxo atual ou, em casos mais extremos, sair do fluxo de forma elegante.

 

FUNÇÃO: DIVISÃO ( NÚMERO: DIVIDENDO, NÚMERO: DIVISOR ) -> NÚMERO: QUOCIENTE
   SE DIVISOR É 0 ENTÃO LANCE EXCEÇÃO: DIVISÃO_POR_ZERO
   RETORNE DIVIDENDO / DIVISOR
   FIM FUNÇÃO

 

A primeira diferença que notamos é: na primeira abordagem poderíamos ter como retorno um NÚMERO ou um NULO. Na segunda abordagem, sempre que houver um retorno ele será do tipo esperado.

 

Dessa forma não encadeamos erros e, de quebra, ganhamos um manipulador para impedir erros consequentes:

 

NÚMERO: QUANTIDADE_ATUAL = 50
NÚMERO: QUANTIDADE_TOTAL = 0
TENTATIVA:
   NÚMERO: PERCENTAGEM = DIVISÃO ( QUANTIDADE_ATUAL, QUANTIDADE_TOTAL ) * 100
EXCETO DIVISÃO_POR_ZERO:
   NÚMERO: PERCENTAGEM = 0
FIM TENTATIVA

 

Na maioria das linguagens, há ainda outra vantagem: Manipulação por tipo de exceção

 

FUNÇÃO: DIVISÃO ( VARIÁVEL: DIVIDENDO, VARIÁVEL: DIVISOR ) -> NÚMERO: QUOCIENTE
   SE (TIPO(DIVIDENDO) = NUMERAL) E (TIPO(DIVISOR) = NUMERAL) É FALSO ENTÃO
       LANCE EXCEÇÃO: ARGUMENTO_INVÁLIDO
   SE DIVISOR É 0 ENTÃO LANCE EXCEÇÃO: DIVISÃO_POR_ZERO
   RETORNE DIVIDENDO / DIVISOR
   FIM FUNÇÃO

VARIÁVEL: QUANTIDADE_ATUAL = [ENTRADA_DO_USUÁRIO]
VARIÁVEL: QUANTIDADE_TOTAL = [ENTRADA_DO_USUÁRIO]
TENTATIVA:
   NÚMERO: PERCENTAGEM = DIVISÃO ( QUANTIDADE_ATUAL, QUANTIDADE_TOTAL ) * 100
EXCETO ARGUMENTO_INVÁLIDO:
   IMPRIMA "POR FAVOR, INFORME DOIS NÚMEROS"
   PARE
EXCETO DIVISÃO_POR_ZERO:
   NÚMERO: PERCENTAGEM = 0
FIM TENTATIVA

 

Como bem observado pelo Henrique, há ainda a possibilidade de empilhar tentativas e, conforme o tipo de exceção, tratar no local adequado, fugindo apenas do fluxo que será impossível atender:

 

FUNÇÃO: DIVISÃO ( VARIÁVEL: DIVIDENDO, VARIÁVEL: DIVISOR ) -> NÚMERO: QUOCIENTE
   SE (TIPO(DIVIDENDO) = NUMERAL) E (TIPO(DIVISOR) = NUMERAL) É FALSO ENTÃO
       LANCE EXCEÇÃO: ARGUMENTO_INVÁLIDO
   SE DIVISOR É 0 ENTÃO LANCE EXCEÇÃO: DIVISÃO_POR_ZERO
   RETORNE DIVIDENDO / DIVISOR
   FIM FUNÇÃO


TENTATIVA:
   VARIÁVEL: QUANTIDADE_ATUAL = [ENTRADA_DO_USUÁRIO]
   VARIÁVEL: QUANTIDADE_TOTAL = [ENTRADA_DO_USUÁRIO]
   TENTATIVA:
       NÚMERO: PERCENTAGEM = DIVISÃO ( QUANTIDADE_ATUAL, QUANTIDADE_TOTAL ) * 100
   EXCETO DIVISÃO_POR_ZERO:
       NÚMERO: PERCENTAGEM = 0
   FIM TENTATIVA
EXCETO ARGUMENTO_INVÁLIDO:
   IMPRIMA "POR FAVOR, INFORME DOIS NÚMEROS"
   PARE
FIM TENTATIVA

 

Observe que no último exemplo, como não será possível continuar sem definir o valor de PERCENTAGEM, o tratamento dessa exceção fica um nível acima do escopo onde a variável é necessária.

Compartilhar este post


Link para o post
Compartilhar em outros sites
É importante que em um bloco try ... catch haja apenas o código crítico, sujeito a erros, e algumas dependências, não o código todo.

 

Além disso, você precisa estar ciente de que TODO o código posterior à chamada que gerou a exceção não será executado.

Do primeiro ponto eu discordo e o segundo eu questiono.

 

Discordo porque eu entendo que todo o código o qual dependa do "código crítico" deve sim ser executado dentro do bloco try e o motivo vêm explicado no porquê de eu questionar.

 

Eu questiono, a segunda afirmação no caso, porque todo ódigo posterior a chamada que gerou a Exception não será executado se a dita Exception não tiver sido pèga. Se ela o tiver, será sim executado:

 

try {

   throw new Exception( 'Message Here' );

} catch( Exception $e ) {

   echo $e -> getMessage();
}

echo '<br /><br />Hello World!';

Esse fragmento mostra na tela ambas as mensagens porque como a Exception foi pêga, pela ausência de um exit/die no bloco catch, o fluxo continua.

 

Agora se apenas o "código crítico" for executado dentro do bloco try, teremos testes, deixando, assim, de confiar na nossa aplicação.

 

Imagine que o "código crítico" seja um método de classe ou função que possa disparar uma Exception antes de retornar alguma coisa. Se disparou antes de retornar, NULL é assumido.

 

$name = NULL; // Evita um Undefined variable

try {

   $name = name();

} catch( Exception $e ) {

   echo $e -> getMessage();
}

function name() {
   throw new Exception( 'Message Here' );
}

if( ! is_null( $name ) ) {
   printf( '<br /><br />Hello %s!', $name );
}

Não sei vocês, mas eu não gosto desse tipo de coisa.

 

Muito melhor seria:

 

try {

   printf( '<br /><br />Hello %s!', name() );

} catch( Exception $e ) {

   echo $e -> getMessage();
}

function name() {
   throw new Exception( 'Message Here' );
}

Claro que nesse exemplo NUNCA será exibida a mensagem, já que a dummy function ali não faz nada mais do que disparar a Exception.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Acho que me fiz entender mal.

O que eu quis dizer foi invés de fazer:

try {

   // trocentas linhas de código
   // trecho crítico
   // código dependente da execução do trecho crítico

} catch( Exception $e ) {

   echo $e -> getMessage();
}

 

Fazer:

// trocentas linhas - 1
try {

   // trecho crítico, que pode lançar uma exceção
   // código dependente da execução do trecho crítico

} catch( Exception $e ) {

   echo $e -> getMessage();
}

 

Por que isso? Na minha humilde opinião torna o código mais legível. Ponto.

Em questões de performance, não muda nada...

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ah bom, então assim, sim! :P

 

Resumindo, até antes de a primeira linha, do primeiro código, que possa disparar a primeira Exception, fora do bloco try. A partir daí, dentro dele. :thumbsup:

 

Eu tenho uma pergunta esse respeito. Os frameworks diversos que vemos por aí afora usam Exceptions para QUALQUER tipo de erro que eles não possam consertar na hora (como um cast forçado).

 

Isso não cabe no conceito de uma Exception, cabe? É apenas uma forma "Orientada a Objetos" (bem entre aspas) para um trigger_error().

 

E aí?

Compartilhar este post


Link para o post
Compartilhar em outros sites
Isso não cabe no conceito de uma Exception, cabe? É apenas uma forma "Orientada a Objetos" (bem entre aspas) para um trigger_error().

 

E aí?

 

Depende muito... É uma característica do PHP, por ser dinamicamente tipada, você não consegue garantir um tipo para o parâmetro sempre.

Se você espera um parâmetro de um certo tipo e tenta garantir isso através de um casting, então o normal é a função/método em questão receber um parâmetro daquele tipo.

Quando o parâmetro é de outro tipo, constitui-se uma exceção à regra de tipo, então, por essa visão, cabe uma exceção.

 

Em Java, por exemplo, não existem "erros" em runtime, só exceções. Se você avaliar que o objetivo de uma aplicação é funcionar corretamente, quando algo dá errado, você tem uma exceção à regra do "deve funcionar".

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.