Try..Catch..End -> número da linha onde ocorre o erro

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Try..Catch..End -> número da linha onde ocorre o erro

Mensagem por asimoes »

Pessoal,

Não sei se é possível,

São erros "tratáveis"

Usando try..catch..end, é possível pegar o número da linha do código, onde no exemplo a=b, a variável b não existe.
Isso para não usar ErrorBlock que mostra a linha onde ocorre o erro mas encerra a aplicação:

Código: Selecionar todos

ErrorBlock( { | oErro | DefError( oErro ) } )

Código: Selecionar todos

   Try
      A=B //variável b não existe
   Catch oErro

   end
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Try..Catch..End -> número da linha onde ocorre o erro

Mensagem por asimoes »

Consegui,
Usando BEGIN..SEQUENCE

Código: Selecionar todos

   BEGIN SEQUENCE WITH {| oError | oError:cargo := { ProcName( 1 ), ProcLine( 1 ) }, Break( oError ) }
      A=B
   RECOVER USING oError   
     ? oError:Cargo[1] //Procname
     ? oError:Cargo[2] //Procline
   END
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Try..Catch..End -> número da linha onde ocorre o erro

Mensagem por fladimir »

:-Y :-Y :-Y
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Try..Catch..End -> número da linha onde ocorre o erro

Mensagem por JoséQuintas »

Se não me engano, a indicação na frente de BEGIN SEQUENCE é só pra quando NÃO vai usar a rotina de erro padrão.
E o TRY/CATCH ou outro, é pra não precisar algo mais.

Uso assim, não sei se interessa pra alguma situação:

Código: Selecionar todos

lOk := .F.
BEGIN SEQUENCE WITH __BreakBlock()
    ...
  lOk := .T.
END SEQUENCE
IF .NOT. lOk
   ? "deu erro na rotina"
ENDIF
Explicação:
Se tudo correr bem, chega até lOk := .T.
Se der algum erro no trajeto, não chega nessa linha, e lOk é .F.

Ou dependendo da rotina, uma variável string que vai se modificando, e no final contém "OK".

Código: Selecionar todos

cStatus := "ERRO"
BEGIN SEQUENCE WITH __BreakBlock()
   cStatus := "sei lá o que"
   ...
   cStatus := "sei lá de novo"
   ...
   cStatus := "ok"
END SEQUENCE
IF cStatus != "ok"
   MsgExclamation( "O erro foi " + cStatus )
ENDIF
Acho que quanto menos exceções melhor, mas cada caso é um caso diferente.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Try..Catch..End -> número da linha onde ocorre o erro

Mensagem por asimoes »

Quintas,

Está correto o seu ponto de vista, o meu exemplo garante em código que tenha um grande número de if´s, do case, etc, e no meio tenha alguma variável atribuindo valor de uma outra que vai gerar um erro, ao indicar a linha do erro facilita para o programador uma rápida correção, concordo que cada caso é um caso.
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Try..Catch..End -> número da linha onde ocorre o erro

Mensagem por JoséQuintas »

Esquisito, nesse caso o BEGIN SEQUENCE até perde o sentido.
Melhor seria atrbiuir valores default.

Eu uso onde sei que pode ocorrer erro.
Exemplo, abrir uma conexão.

Código: Selecionar todos

METHOD Open( lError ) CLASS ADOClass

   LOCAL lOk := .F., nCont, cMessage

   hb_Default( @lError, .T. )
   WSave( MaxRow() - 1, 0, MaxRow(), MaxCol() )
   FOR nCont = 1 TO 5
      BEGIN SEQUENCE WITH __BreakBlock()
         IF ::cn:State() != AD_STATE_OPEN
            ::Cn:Open()
         ENDIF
         DO WHILE ::cn:State() != AD_STATE_OPEN
            Inkey(1)
         ENDDO
         lOk := .T.
      END SEQUENCE
      IF lOk
         EXIT
      ENDIF
      Mensagem( "Falhou pra conectar com servidor, tentativa " + LTrim( Str( nCont ) ) + "/5" )
      BEGIN SEQUENCE WITH __BreakBlock()
         cMessage := LTrim( Str( ::Cn:Errors(0):Number() ) ) + " " + ::Cn:Errors(0):Description()
         Mensagem( cMessage )
         WriteErrorLog( cMessage, 2 )
      END SEQUENCE
      Inkey(10)
   NEXT
   IF lError .AND. .NOT. lOk
      Eval( ErrorBlock() )
      QUIT
   ENDIF
   WRestore()

   RETURN lOk
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Try..Catch..End -> número da linha onde ocorre o erro

Mensagem por JoséQuintas »

Esta aqui também é legal, pra testar macro:

Código: Selecionar todos

cFiltro := "cliente->Código == 5 .and. cliente->Cidade=='SAO PAULO'"

IF MacroType( cFiltro ) != "L"
   MsgExclamation( "Expressão inválida para filtro" )
ENDIF
...

FUNCTION MacroType( cExpression )

   LOCAL cType := "U", bBlock

   BEGIN SEQUENCE WITH __BreakBlock()
      bBlock := hb_MacroBlock( cExpression )
      cType  := ValType( Eval( bBlock ) )
   END SEQUENCE

   RETURN cType
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Try..Catch..End -> número da linha onde ocorre o erro

Mensagem por asimoes »

Quintas,

O intuito é esse mesmo, estamos usando agora begin..sequence do exemplo em uma classe que faz operações no banco oracle.

Usava-se antes o try..catch, mas o try..catch tem limitações.

E no recover, estamos enviando email para a equipe responsável pelo sistema, estes sistemas são corporativos da prefeitura.

Aconteceu um problema no banco esta semana onde um colega nosso simplesmente tirou os grants do usuário aplicação do banco e começou a pipocar erro, só que ficava em try..catch e o usuário não estava nos informando o que estava acontecendo, enfim agora todos nós vamos saber quando acontecer de novo.
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Try..Catch..End -> número da linha onde ocorre o erro

Mensagem por JoséQuintas »

Uso isto.
Até o comando SQL usado vém na mensagem de erro.

Código: Selecionar todos

METHOD ExecuteCmd( cSql, lError ) CLASS ADOClass

   LOCAL lOk := .F., cMensagem := "", Rs

   IF ::Cn == NIL
      RETURN NIL
   ENDIF
   hb_Default( @lError, .T. )
   cSql := iif( cSql == NIL, ::cSql, cSql ) // não pode usar hb_Default
   IF ::Cn:State() != AD_STATE_OPEN
      ::Open()
   ENDIF
   cSql := Trim( cSql )
   IF Right( AllTrim( cSql ), 1 ) != ";"
      cSql += ";"
   ENDIF
   IF Len( Trim( cSql ) ) != 0
      BEGIN SEQUENCE WITH __BreakBlock()
         Rs := ::Cn:Execute( cSql )
         lOk := .T.
      ENDSEQUENCE
      IF .NOT. lOk
         cMensagem += "Erro executando comando:" + LTrim( Str( ::Cn:Errors( 0 ):Number( ) ) ) + " " + ::Cn:Errors( 0 ):Description()
         WriteErrorLog( cMensagem )
         WriteErrorLog( cSql, 2 )
         IF lError
            Eval( ErrorBlock() )
            QUIT
         ENDIF
      ENDIF
   ENDIF

   RETURN Rs
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Try..Catch..End -> número da linha onde ocorre o erro

Mensagem por JoséQuintas »

Aproveitar que deu erro nos testes pra mostrar como sai minha mensagem de erro.

Código: Selecionar todos

Erro executando comando:-2147217900 [MySQL][ODBC 3.51 Driver][mysqld-5.7.12-log]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'HLDIMRAT WHERE LOCADOR=1764 LOCATARIO=1764010 AND CIC='xxx'' at line 1
--------------------------------------------------------------------------------
Error on 28/08/2016 22:41:52
JPA: 2016.08.28.2240
Login JPA: JOSEQ
Alias:  TEMPRATEIO
MySQL local: SIM

Harbour: Harbour 3.4.0dev (b6c8382) (2016-08-12 12:06)
Compiler: Microsoft Visual C++ 16.0.40219 (32-bit)
GT: WVG
Folder: d:\JPA\haroldo\locacao\
Windows: Windows 7 6.1 SP1
Computer Name: JOSEJPA

DELETE FORM HLDIMRAT WHERE LOCADOR=1764 LOCATARIO=1764010 AND CIC='xxxx';
Called from PDIMOBFUNCRATEIOTBROWSE(584)  
Called from (b)RATEIOTBROWSE(553)  
Called from DBVIEW(156)  
Called from RATEIOTBROWSE(553)  
Called from PDIMOBFUNCLOCATARIOTBROWSE(464)  
Called from (b)LOCATARIOTBROWSE(415)  
Called from DBVIEW(156)  
Called from LOCATARIOTBROWSE(415)  
Called from PDIMOBFUNCLOCADORTBROWSE(265)  
Called from (b)LOCADORTBROWSE(235)  
Called from DBVIEW(156)  
Called from LOCADORTBROWSE(235)  
Called from PDIMOBCAD(34)  
Called from DO(0)  
Called from BOXMENU(497)  
Called from BOXMENU(479)  
Called from MAINMENU(347)  
Called from MAIN(107)  
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Try..Catch..End -> número da linha onde ocorre o erro

Mensagem por Vlademiro »

Não precisa usar a variável lOk para controlar o erro, basta fazer conforme o exemplo abaixo:

Código: Selecionar todos


 BEGIN SEQUENCE WITH __BreakBlock()
      oInmail := TIPClientSMTP():New( oUrl, xTrace,, cClientHost )
   RECOVER
      RETURN .F.  // Executa somente se deu erro 
   END SEQUENCE
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Try..Catch..End -> número da linha onde ocorre o erro

Mensagem por JoséQuintas »

Por coincidência vi isso hoje.
Olhei em hbcompat.ch a definição de TRY/CATCH.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Try..Catch..End -> número da linha onde ocorre o erro

Mensagem por JoséQuintas »

E voltando ao assunto que deu origem a tudo:

A errorsys normal já mostra erro, com linha e toda callstack.
Porque BEGIN SEQUENCE, se vai fazer exatamente a mesma coisa?
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Try..Catch..End -> número da linha onde ocorre o erro

Mensagem por asimoes »

Porque o programador pode tratar o erro e decidir se encerra a aplicação ou não
Errorsys encerra a aplicação
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Responder