Ir para o conteúdo

Publicidade

 Estatísticas do Fórum

  • 0 Usuários ativos

    0 membro(s), 0 visitante(s) e 0 membros anônimo(s)

Cursos Online iMasters
Foto:

Estrutura Try Catch

  • Por favor, faça o login para responder
16 respostas neste tópico

#1 Carcleo

Carcleo
  • Membros
  • 1.735 posts

Postado 15 maio 2012 - 07:30

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&aacute;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();
	  }
}
?>

Editado por Mário Monteiro, 16 maio 2012 - 15:23 .
Retirada a palavra "DÚVIDA" do Titulo ou Descrição

  • 0

#2 Guilherme_90

Guilherme_90

    Guilherme Nogueira

  • Membros
  • 663 posts

Postado 15 maio 2012 - 10:12

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?
  • 0

#3 Vinicius Rangel

Vinicius Rangel
  • Membros
  • 2.100 posts

Postado 15 maio 2012 - 10:23

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...
  • 0

#4 Carcleo

Carcleo
  • Membros
  • 1.735 posts

Postado 15 maio 2012 - 10:33

Entendi.

Vou vere o que mudar aqui e reposto como ficou
  • 0

#5 Henrique Barcelos

Henrique Barcelos

    ♪♫

  • Moderadores
  • 4.659 posts

Postado 15 maio 2012 - 10:45

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.
  • 1

#6 Guilherme_90

Guilherme_90

    Guilherme Nogueira

  • Membros
  • 663 posts

Postado 15 maio 2012 - 10:45

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:
  • 0

#7 Prog

Prog

    Enterprise Search Specialist

  • Moderadores
  • 5.234 posts

Postado 15 maio 2012 - 10:58

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.
  • 0

#8 Vinicius Rangel

Vinicius Rangel
  • Membros
  • 2.100 posts

Postado 15 maio 2012 - 11:06

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.
  • 0

#9 Luis Paullo

Luis Paullo

    echo 'noob PHP';

  • Membros
  • 563 posts

Postado 15 maio 2012 - 11:15

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!
  • 0

#10 Guilherme_90

Guilherme_90

    Guilherme Nogueira

  • Membros
  • 663 posts

Postado 15 maio 2012 - 11:28

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;
}
?>

Editado por Guilherme_90, 15 maio 2012 - 11:44 .

  • 0

#11 Vinicius Rangel

Vinicius Rangel
  • Membros
  • 2.100 posts

Postado 15 maio 2012 - 11:38

Isso PRA mim se chamada gambiarra, #@?$%~ gambiarra.


siim, uahuhauhauhahuahuuhaa.
gambiarra total do mesmo modo que é tratar os erros com if else
  • 0

#12 Evandro Oliveira

Evandro Oliveira

    leia ali -->

  • Membros
  • 4.568 posts

Postado 15 maio 2012 - 12:25

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.
  • 2

#13 Henrique Barcelos

Henrique Barcelos

    ♪♫

  • Moderadores
  • 4.659 posts

Postado 15 maio 2012 - 15:11

@Evandro Oliveira, show!!! :clap:
  • 0

#14 Bruno Augusto

Bruno Augusto

    Sou Bobo Também ¬¬

  • Moderadores
  • 6.333 posts

Postado 15 maio 2012 - 16:15

É 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.
  • 0

#15 Henrique Barcelos

Henrique Barcelos

    ♪♫

  • Moderadores
  • 4.659 posts

Postado 15 maio 2012 - 17:14

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...

  • 0

#16 Bruno Augusto

Bruno Augusto

    Sou Bobo Também ¬¬

  • Moderadores
  • 6.333 posts

Postado 15 maio 2012 - 19:44

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í?
  • 0

#17 Henrique Barcelos

Henrique Barcelos

    ♪♫

  • Moderadores
  • 4.659 posts

Postado 15 maio 2012 - 23:14

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".
  • 1




Publicidade

/ins>