:TITLE: Depuração e Erros - errorInfo errorCode catch error return
;#
;# RCSID: $Header: /home/clif/CVS_ROOT/TclTutor/Tcl36.lsn,v 1.5 2000/04/24 16:17:52 clif Exp $
;# Copyright (c) 1995 Clif Flynt
;# 9300 Fleming Rd.
;# Dexter, MI  48130
;# clif@cflynt.com
;# Veja o arquivo "AVISO" com os termos da licença.
;#
;#*********************************************************
;# Portuguese translation: Lucio Agostinho Rocha
;# E-mail: outrosdiasvirao@yahoo.com.br
;# Last update: 16/01/2006
;#*********************************************************
:LESSON_TEXT_START_LEVEL 0:
Comandos Tcl e procs retornam um status e um valor.
Um comando ou proc sempre retorna um status, e pode
opcionalmente retornar um valor.
<P>
Quando um comando executa corretamente, o status de retorno
é TCL_OK. Quando um erro ocorre dentro de um comando Tcl,
ele retorna TCL_ERROR ao invés de TCL_OK. Quando isso
ocorre, o comando Tcl que tinha o erro coloca uma string de
informação na variável global errorInfo e
retorna um status de TCL_ERROR para o comando.
Como a pilha de chamada não se esvazia, cada comando Tcl adiciona
um mensagem de informação à variável global errorInfo, e retorna
TCL_ERROR ao comando acima dele.
<P>
Isso atualmente ocorre quando qualquer condição de exceção acontece,
incluindo <B>break</B> e <B>continue</B>. <B>Break</B> e <B>continue</B> 
normalmente ocorrem dentro de um laço de alguma ordenação, e o comando
de laço captura a exceção e a processa de acordo.
<P>
Código Tcl interpretado pode também capturar exceções. Se um comando Tcl
é o argumento para o comando <B>catch</B>, qualquer exceção que o comando
gera é capturada e retornada. Neste ponto, o proc que chamou o comando
pode decidir como manipular o evento.
<DL>
<B><DT>error</B> <I>mensagem ?info? ?codigo?</I>
<DD>Gera uma condição de erro e força Tcl a esvaziar a pilha, com
uma informação de erro sendo adicionada a cada passo.
<P>
Se <I>info</I> ou <I>codigo</I> são fornecidos, as variáveis errorInfo e
errorCode são inicializadas com esses valores.
<B><DT>catch</B> <I>script ?nomeVar?</I>
<DD>Avalia e executa o <I>script</I>. O valor de retorno de catch
é o retorno de status do interpretador Tcl depois que ele executa o
<I>script</I>. Se não houver erros no <I>script</I>, este valor é TCL_OK. Caso
contrário é um valor de erro.
<P>
Se <I>nomeVar</I> é fornecido, o valor retornado pelo <I>script</I> é
colocado em <I>nomeVar</I>.
<B><DT>return</B> <I>?-code codigo? ?-errorinfo info? ?-errorcode codigoErro? ?valor?</I>
<DD>Gera um retorno de condição de exceção. Os possíveis argumentos são:
<DL>
<I><DT>-code</I> 
<DD> o próximo valor especifica o status de retorno.
<I>Codigo</I> deve ser um dos seguintes:
<UL>
<PRE><CODE>
ok ........ Retorno o status normal
error ..... Proc retorna um status de erro
return .... Retorno normal
break ..... Proc retorna um status de break
continue .. Proc retorna um status de continue
</CODE></PRE>
<I><DT>-errorinfo</I>
<DD> <I>info</I> será a primeira string na variável <B>errorInfo</B>.
<I><DT>-errorcode</I>
<DD> O proc irá atribuir <B>codigoErro</B> a <I>errorcode</I>.
<I><DT>valor</I>
<DD> A string <I>valor</I> será o valor retornado por esse proc.
</UL>
</DL>
<B><DT>errorInfo</B>
<DD><B>errorInfo</B> é uma variável global que contém a informação de erro
dos comandos que falharam.
<B><DT>errorCode</B>
<DD><B>errorCode</B> é uma variável global que contém o código de erro do 
comando que falhou.
</DL>
:TEXT_END:

:LESSON_TEXT_START_LEVEL 1:
Nas lições anteriores nós discutimos como o comando <B>return</B> poderia
ser usado para retornar um valor de um proc. Em Tcl, um proc pode
retornar um valor, mas ele sempre retorna um status.
<P>
Quando um comando executa corretamente, o status de retorno
é TCL_OK. Quando um erro ocorre dentro de um comando Tcl,
ele retorna TCL_ERROR ao invés de TCL_OK. Quando isso
ocorre, o comando Tcl que tinha o erro coloca uma string de
informação na variável global errorInfo e
retorna um status de TCL_ERROR para o comando.
Como a pilha de chamada não se esvazia, cada comando Tcl adiciona
um mensagem de informação à variável global errorInfo, e retorna
TCL_ERROR ao comando acima dele.
<P>
Isso atualmente ocorre quando qualquer condição de exceção acontece,
incluindo <B>break</B> e <B>continue</B>. <B>Break</B> e <B>continue</B> 
normalmente ocorrem dentro de um laço de alguma ordenação, e o comando
de laço captura a exceção e a processa de acordo.
<P>
Código Tcl interpretado pode também capturar exceções. Se um comando Tcl
é o argumento para o comando <B>catch</B>, qualquer exceção que o comando
gera é capturada e retornada. Neste ponto, o proc que chamou o comando
pode decidir como manipular o evento.
<P>
Por exemplo, se uma chamada <B>open</B> retorna um erro, o usuário
poderia ser sugerido a fornecer outro nome de arquivo.
<P>
Um proc Tcl também pode gerar um status de condição de erro. Isso pode
ser feito especificando um retorno de erro com um opção para o comando
<B>return</B>, ou usando o comando <B>error</B>. Em outro caso, uma
mensagem será colocada em <B>errorInfo</B>, e o proc irá retornar um
status TLC_ERROR.
<DL>
<B><DT>error</B> <I>mensagem ?info? ?codigo?</I>
<DD>Gera uma condição de erro e força Tcl a esvaziar a pilha, com
uma informação de erro sendo adicionada a cada passo.
<P>
Se <I>info</I> ou <I>codigo</I> são fornecidos, as variáveis errorInfo e
errorCode são inicializadas com esses valores.
<B><DT>catch</B> <I>script ?nomeVar?</I>
<DD>Avalia e executa o <I>script</I>. O valor de retorno de catch
é o retorno de status do interpretador Tcl depois que ele executa o
<I>script</I>. Se não houver erros no <I>script</I>, este valor é TCL_OK. Caso
contrário é um valor de erro.
<P>
Se <I>nomeVar</I> é fornecido, o valor retornado pelo <I>script</I> é
colocado em <I>nomeVar</I>.
<B><DT>return</B> <I>?-code codigo? ?-errorinfo info? ?-errorcode codigoErro? ?valor?</I>
<DD>Gera um retorno de condição de exceção. Os possíveis argumentos são:
<DL>
<I><DT>-code</I> 
<DD> o próximo valor especifica o status de retorno.
<I>Codigo</I> deve ser um dos seguintes:
<UL>
<PRE><CODE>
ok ........ Retorno o status normal
error ..... Proc retorna um status de erro
return .... Retorno normal
break ..... Proc retorna um status de break
continue .. Proc retorna um status de continue
</CODE></PRE>
<I><DT>-errorinfo</I>
<DD> <I>info</I> será a primeira string na variável <B>errorInfo</B>.
<I><DT>-errorcode</I>
<DD> O proc irá atribuir <B>codigoErro</B> a <I>errorcode</I>.
<I><DT>valor</I>
<DD> A string <I>valor</I> será o valor retornado por esse proc.
</UL>
</DL>
<B><DT>errorInfo</B>
<DD><B>errorInfo</B> é uma variável global que contém a informação de erro
dos comandos que falharam.
<B><DT>errorCode</B>
<DD><B>errorCode</B> é uma variável global que contém o código de erro do 
comando que falhou.
</DL>
:TEXT_END:

:LESSON_TEXT_START_LEVEL 2:
Nas lições anteriores nós discutimos como o comando <B>return</B> poderia ser
usado para retornar um valor de um proc, e como alguns comandos (tais como o
comando <B>string match</B>) retornam um código de sucesso ou falha quando
eles executam. Este valor que é explicitamente retornado é apenas um dos
valores que são retornados. Todos os comandos Tcl também retornam um status
quando eles executam. O retorno de status diz se o comando executou corretamente,
ou se uma exceção ocorreu enquanto ele estava executando.
<P>
Por exemplo, quando um comando <B>string match</B> encontra um modelo
compatível, ele retorna 1 para seu valor de retorno. Ele também retorna
TCL_OK como seu status. Se não for encontrado um modelo compatível,
<B>string match</B> retornaria um 0, mas o status seria ainda 
TCL_OK. Todavia, se <B>string match</B> fosse chamado com apenas um
argumento, ele retornaria uma string de erro, e o status retornado
seria TCL_ERROR.
<P>
Quando um comando executa corretamente, o status de retorno
é TCL_OK. Quando um erro ocorre dentro de um comando Tcl,
ele retorna TCL_ERROR ao invés de TCL_OK. Quando isso
ocorre, o comando Tcl que tinha o erro coloca uma string de
informação na variável global errorInfo e
retorna um status de TCL_ERROR para o comando.
Como a pilha de chamada não se esvazia, cada comando Tcl adiciona
um mensagem de informação à variável global errorInfo, e retorna
TCL_ERROR ao comando acima dele.
<P>
Isso atualmente ocorre quando qualquer condição de exceção acontece,
incluindo <B>break</B> e <B>continue</B>. <B>Break</B> e <B>continue</B> 
normalmente ocorrem dentro de um laço de alguma ordenação, e o comando
de laço captura a exceção e a processa de acordo.
<P>
Código Tcl interpretado pode também capturar exceções. Se um comando Tcl
é o argumento para o comando <B>catch</B>, qualquer exceção que o comando
gera é capturada e retornada. Neste ponto, o proc que chamou o comando
pode decidir como manipular o evento.
<P>
Por exemplo, se uma chamada <B>open</B> retorna um erro, o usuário
poderia ser sugerido a fornecer outro nome de arquivo.
<P>
Um proc Tcl também pode gerar um status de condição de erro. Isso pode
ser feito especificando um retorno de erro com um opção para o comando
<B>return</B>, ou usando o comando <B>error</B>. Em outro caso, uma
mensagem será colocada em <B>errorInfo</B>, e o proc irá retornar um
status TLC_ERROR.
<P>
O exemplo de código mostra o comando <B>catch</B> sendo usado muitas vezes.
Todos os procs neste exemplo irão gerar uma exceção. O comando 
<B>catch</B> é usado para capturar aquela exceção. Depois que a exceção
foi capturada, <B>errorInfo</B> e <B>errorCode</B> são exibidos.
<P>
Execute o exemplo, e examine a saída. Você verá que <B>errorInfo</B>
é sempre atribuída se um erro ocorre, mas errorCode pode não ser
atribuída. O último exemplo, tentando abrir um arquivo não existente,
atribui 
errorCode.
<DL>
<B><DT>error</B> <I>mensagem ?info? ?codigo?</I>
<DD>Gera uma condição de erro e força Tcl a esvaziar a pilha, com
uma informação de erro sendo adicionada a cada passo.
<P>
Se <I>info</I> ou <I>codigo</I> são fornecidos, as variáveis errorInfo e
errorCode são inicializadas com esses valores.
<B><DT>catch</B> <I>script ?nomeVar?</I>
<DD>Avalia e executa o <I>script</I>. O valor de retorno de catch
é o retorno de status do interpretador Tcl depois que ele executa o
<I>script</I>. Se não houver erros no <I>script</I>, este valor é TCL_OK. Caso
contrário é um valor de erro.
<P>
Se <I>nomeVar</I> é fornecido, o valor retornado pelo <I>script</I> é
colocado em <I>nomeVar</I>.
<B><DT>return</B> <I>?-code codigo? ?-errorinfo info? ?-errorcode codigoErro? ?valor?</I>
<DD>Gera um retorno de condição de exceção. Os possíveis argumentos são:
<DL>
<I><DT>-code</I> 
<DD> o próximo valor especifica o status de retorno.
<I>Codigo</I> deve ser um dos seguintes:
<UL>
<PRE><CODE>
ok ........ Retorno o status normal
error ..... Proc retorna um status de erro
return .... Retorno normal
break ..... Proc retorna um status de break
continue .. Proc retorna um status de continue
</CODE></PRE>
<I><DT>-errorinfo</I>
<DD> <I>info</I> será a primeira string na variável <B>errorInfo</B>.
<I><DT>-errorcode</I>
<DD> O proc irá atribuir <B>codigoErro</B> a <I>errorcode</I>.
<I><DT>valor</I>
<DD> A string <I>valor</I> será o valor retornado por esse proc.
</UL>
</DL>
<B><DT>errorInfo</B>
<DD><B>errorInfo</B> é uma variável global que contém a informação de erro
dos comandos que falharam.
<B><DT>errorCode</B>
<DD><B>errorCode</B> é uma variável global que contém o código de erro do 
comando que falhou.
</DL>
:TEXT_END:

:CODE_START:
proc procErro {x} { 
  if {$x > 0} {
    error "Erro gerado por 'error'" "String de informação para error" $x
    }
  }

catch procErro
puts "depois de uma chamada errada ao proc: ErrorCode: $errorCode"
puts "ERRORINFO:\n$errorInfo\n"

set errorInfo ""
catch {procErro 0}
puts "depois de chamar o proc sem error: ErrorCode: $errorCode"
puts "ERRORINFO:\n$errorInfo\n"

catch {procErro 2}
puts "depois do erro gerado no proc: ErrorCode: $errorCode"
puts "ERRORINFO:\n$errorInfo\n"


proc returnErr { x } {
  return -code error -errorinfo "Retorno gera isso" -errorcode "-999"
  }

catch {returnErr 2}
puts "depois do proc que usa o retorno para gerar um erro: ErrorCode: $errorCode"
puts "ERRORINFO:\n$errorInfo\n"

proc comErro {x} {
  set x $a
  }

catch {comErro 2}
puts "depois do proc com um erro: ErrorCode: $errorCode"
puts "ERRORINFO:\n$errorInfo\n"

catch {open /diretorio_nao_encontrado/arquivo_nao_encontrado r}
puts "depois de uma chamada errada a um arquivo inexistente:"
puts "ErrorCode: $errorCode"
puts "ERRORINFO:\n$errorInfo\n"

:TEXT_END:
