Página 1 de 1
Try..Catch..End -> número da linha onde ocorre o erro
Enviado: 26 Ago 2016 20:57
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:
Try..Catch..End -> número da linha onde ocorre o erro
Enviado: 26 Ago 2016 21:35
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
Try..Catch..End -> número da linha onde ocorre o erro
Enviado: 27 Ago 2016 00:29
por fladimir
:-Y :-Y :-Y
Try..Catch..End -> número da linha onde ocorre o erro
Enviado: 27 Ago 2016 11:44
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.
Try..Catch..End -> número da linha onde ocorre o erro
Enviado: 27 Ago 2016 13:10
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.
Try..Catch..End -> número da linha onde ocorre o erro
Enviado: 27 Ago 2016 13:38
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
Try..Catch..End -> número da linha onde ocorre o erro
Enviado: 27 Ago 2016 13:44
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
Try..Catch..End -> número da linha onde ocorre o erro
Enviado: 27 Ago 2016 17:23
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.
Try..Catch..End -> número da linha onde ocorre o erro
Enviado: 27 Ago 2016 18:19
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
Try..Catch..End -> número da linha onde ocorre o erro
Enviado: 28 Ago 2016 22:47
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)
Try..Catch..End -> número da linha onde ocorre o erro
Enviado: 14 Dez 2016 15:16
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
Try..Catch..End -> número da linha onde ocorre o erro
Enviado: 14 Dez 2016 16:17
por JoséQuintas
Por coincidência vi isso hoje.
Olhei em hbcompat.ch a definição de TRY/CATCH.
Try..Catch..End -> número da linha onde ocorre o erro
Enviado: 14 Dez 2016 16:21
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?
Try..Catch..End -> número da linha onde ocorre o erro
Enviado: 15 Dez 2016 09:27
por asimoes
Porque o programador pode tratar o erro e decidir se encerra a aplicação ou não
Errorsys encerra a aplicação