Jump to content

Compre o Delphi
Com até 30% de desconto
e parcelado em até 12x sem juros

Saiba Mais

Balança SM100 performance surpreendente

Tecnologia Japonesa   Teclado e Visor resistentes a água
Consumo inteligente de etiquetas   Baixo custo de manutenção
Comunicação Ethernet e WIFI independentes

Saiba mais

Impressora de Etiquetas ELGIN - L42 PRO

Protocolos PPLA, PPLB, ZPL, EPL (automático)
Porta USB padrão Opcionais: Ethernet, Serial, Paralela
Sensor de Etiquetas Móvel Garantia de 18 meses

Saiba mais

Recommended Posts

Olá queridos companheiros, pesquisei muito sobre uma forma de tratar erros inesperados que causam o fechamento da aplicação e acabei descobrindo (ou inventando kkk), um modo de tratar todos os erros que não foram tratados, vi uma postagem de mais de um ano aq no forum mas não puder dar sequencia nela por estar fechada.

Nesse post vi a sugestão do componente TApplicationProperties, para usar seu evento OnException, mas ao tentar usar ele,  disparava 3 vezes, sem contar que ao colocar um componente em um form e herda-lo, ele componente fica aparecendo em todos os forms e eu só meio xarope e isso me incomoda. 😅 

Seguinte.... Eu uso um FormPadrao no qual estão todas procedures (ferramentas) criadas por mim e algumas outras facilidades como mudar de campo com Enter, fechar as janelas com Esc, etc. E derivo todos os meus outros forms desse para herdarem essas funções e propriedades. Nele eu criei o seguinte procedimento.

//================================== Inicio do Procedimento ==================================\\

procedure TFormPadrao.OnException(Sender: TObject; E: Exception);
var
  auxLog: TextFile;
begin
  try
    AssignFile(auxLog, 'Log_Exceptions.txt');

    if (FileExists('Log_Exceptions.txt')) then
    begin
      Append(auxLog);
    end
    else
    begin
      Rewrite(auxLog);
      WriteLn(auxLog, 'Log de Erros!');
      WriteLn(auxLog, '');
    end;
    WriteLn(auxLog, FormatDateTime('dd/MM/yyyy - hh:mm:ss',now) +
    ' => Origem: ' + Sender.ToString + ' => Erro: ' + E.Message);
  finally
    CloseFile(auxLog);
  end;

  Riba.Aviso('Origem: ' + Sender.ToString + ' => Erro: ' + E.Message);

  if(Sender is TForm)then
    (Sender as TForm).Close;
end;

 

//================================== Fim do Procedimento ==================================\\

E no evento onCreate eu digitei essa linha que associa um procedimento ao um evento

Application.OnException := @OnException;

 

Agora todo erro não tratado é mostrado na tela, fecha só o form que deu o erro e faz um log dos erros.

obs. Esse Riba.Aviso é pra mostrar mensagens na tela do meu jeito. 😁

 

Se eu fiz algo errado no post me corrijam por favor pois é meu primeiro post compartilhando informação.

DEUS abençoe a todos.

 

Edited by RibaSoft
  • Like 1

Share this post


Link to post
Share on other sites

Boa tarde.

Obrigada por compartilhar sua solução.

Att.

  • Like 1

Consultora SAC ACBr

Juliana Tamizou
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil

Share this post


Link to post
Share on other sites

Olá.

   Eu particularmente gosto de analisar sugestões criativas como a sua. Acho que nos acrescenta muito. Dito isso, tenho os seguintes comentários:

4 horas atrás, RibaSoft disse:

Nesse post vi a sugestão do componente TApplicationProperties, para usar seu evento OnException, mas ao tentar usar ele,  disparava 3 vezes, sem contar que ao colocar um componente em um form e herda-lo, ele componente fica aparecendo em todos os forms e eu só meio xarope e isso me incomoda. 😅 

   hmm... talvez o seu problema esteja em colocar o TApplicationproperties no seu FormPadrao. Você deve ter apenas uma instância do TApplicationProperties na sua aplicação. Geralmente coloca-se num DataModule que não vai ser criado e destruído mais de uma vez.

4 horas atrás, RibaSoft disse:

E no evento onCreate eu digitei essa linha que associa um procedimento ao um evento

Application.OnException := @OnException;

   O problema ao fazer isso é que cada form criado sobrepõe o Application.OnException do Form anterior. Isso pode levar a uma inconsistência.

   Acredito que se você criar um dois forms em sequência, o segundo for destruído e então o primeiro gerar uma exception você terá um AccessViolation.

 

  • Like 2

[]'s

Consultor SAC ACBr

Elton
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.

Share this post


Link to post
Share on other sites

Boa noite fico muito contente pelas suas explicações, vou tentar coloca-las em prática.

Só para entender melhor, meu form padrão nunca é criado (instanciado),  ele serve apenas para que os forms herdeiros herdem seus eventos e propriedades, o meu form que é instanciado junto com o sistema é o formPrincipal que também é herdeiro do form padrão,  minha duvida é:

Se esse evento o Application.OnException que é herdado pode dar problemas, o meus outros eventos herdados tambem podem dar problemas? tipo o onKeyPress que uso para fechar todos os forms com o ESC?

Sou autodidata por isso não tenho tanta experiência, acho que não venho usando corretamente a herança de classes. Preciso estudar mais. 😅

Edited by RibaSoft

Share this post


Link to post
Share on other sites
36 minutos atrás, RibaSoft disse:

Só para entender melhor, meu form padrão nunca é criado (instanciado),  ele serve apenas para que os forms herdeiros herdem seus eventos e propriedades, o meu form que é instanciado junto com o sistema é o formPrincipal que também é herdeiro do form padrão,  minha duvida é:

Não quis dizer que o "form padrão" fosse criado, mas sim os forms que herdam dele que possuem o mesmo evento onCreate que você descreveu acima. Dito isso:

38 minutos atrás, RibaSoft disse:

Se esse evento o Application.OnException que é herdado pode dar problemas, o meus outros eventos herdados tambem podem dar problemas? tipo o onKeyPress que uso para fechar todos os forms com o ESC?

Creio que não, porque esses outros eventos são de cada form. Mas o evento Application.OnException é da aplicação (Application).

Application é na verdade uma variável global da aplicação. Por isso, toda vez que você faz:

7 horas atrás, RibaSoft disse:

Application.OnException := @OnException;

Você está na verdade sobrescrevendo o mesmo evento com uma procedure do form que foi criado agora.

  • Like 1

[]'s

Consultor SAC ACBr

Elton
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.

Share this post


Link to post
Share on other sites

Show a explicação, só uma ultima pergunta se não for abusar, eu usando o componente mencionado no datamodulo ele pegara as exception de toda a aplicação? pela logica acho que sim né pois vc falou que se trata de um evento da aplicação e não do form.

Share this post


Link to post
Share on other sites

Arrumei conforme vc falou, testei no DataModulo e no FormPrincipal, o ruim de fazer assim é que não vem o nome do Form no Sender, dai meu log não vai registrar da onde veio o erro, e nem consigo fechar aquele form especifico, mas se fica mais estável vou seguir seu conselho e deixar como está, pelo menos não aparece mais o abort que o cliente sempre clica e fecha toda a aplicação.

DEUS abençoe pela ajuda. 

  • Like 1

Share this post


Link to post
Share on other sites
Em 13/09/2019 at 01:15, RibaSoft disse:

Arrumei conforme vc falou, testei no DataModulo e no FormPrincipal, o ruim de fazer assim é que não vem o nome do Form no Sender, dai meu log não vai registrar da onde veio o erro, e nem consigo fechar aquele form especifico,

Hmm... Acho que estamos com ideias diferentes. Eu não vejo o Application.onException com o objetivo de tratar erros num form específico. Eu o vejo como um modo pra tratar exceptions que fugiram todos os tratamentos nos forms.

Nesses casos, o ideal é você registrar o CallStack da exception, de modo que você vai saber exatamente não só onde aconteceu, mas também o percurso que o código fez pra gerar o erro.

 

Em 13/09/2019 at 01:15, RibaSoft disse:

mas se fica mais estável vou seguir seu conselho e deixar como está

Fica mais estável porque você estava sobrescrevendo o Application.onException. Você pode remover o código que faz isso e daí usar um TApplicationEvents para cada form como queria.

O detalhe é que nesse caso, todos os forms abertos vão receber o evento. Daí você deve usar o método CancelDispatch para impedir a propagação pros próximos forms.

Queria acrescentar que esse modelo eu nunca trabalhei... mas não me parece vantajoso.

  • Like 2

[]'s

Consultor SAC ACBr

Elton
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.

Share this post


Link to post
Share on other sites

Não devo ter me espessado direito, mas é exatamente o que preciso, tratar erros que não foram tratados e criar um log que me ajude a identificar a origem do erro, não tenho palavras pra agradecer sua ajuda em me orientar, vou pesquisar sobre o callstack pois não sei como funciona, e quanto ao segundo modo citado, realmente não parece haver vantagens. DEUS abençoe pela ajuda. 🙏

Share this post


Link to post
Share on other sites

Eureca!!!

Ficou assim...

No DataModulo

//Adiciona a procedure ao evento

Application.OnException := @OnException;  //Forms 

//============================= ON EXCEPTION =================================\\
procedure TDataModulo.OnException(Sender: TObject; E: Exception);
var
  auxLog: TextFile;
begin
  try
    AssignFile(auxLog, 'Log_Exceptions.txt');

    if (FileExists('Log_Exceptions.txt')) then
    begin
      Append(auxLog);
    end
    else
    begin
      Rewrite(auxLog);
      WriteLn(auxLog, 'Log de Erros!');
      WriteLn(auxLog, '');
    end;

    WriteLn(auxLog, FormatDateTime('dd/MM/yyyy - hh:mm:ss',now) +
    '=> Erro: ' + E.ClassName + ' - ' + E.Message);

//Aqui é onde registra os detalhes do erro
    DumpExceptionBackTrace(auxLog);
    WriteLn(auxLog, '======================================================='+
    '================================');

  finally
    CloseFile(auxLog);
  end;

  Riba.Aviso('Erro: ' + E.ClassName + ' - '  + E.Message);
end;          

//=============================== RESULTADO DO LOG

17/09/2019 - 00:40:48=> Erro: EConvertError - " " is an invalid integer
  $00501536
  $0045C6C7  TFORMCLIENTES__EDITBUSCARCHANGE,  line 290 of unitClientes.pas
  $005DB395  TCUSTOMEDIT__CHANGE,  line 652 of ./include/customedit.inc
  $005DB33A  TCUSTOMEDIT__TEXTCHANGED,  line 644 of ./include/customedit.inc
  $005BCD6B  TCONTROL__CMTEXTCHANGED,  line 1203 of ./include/control.inc
  $0040E828
  $005B4801  TWINCONTROL__WNDPROC,  line 5419 of ./include/wincontrol.inc
  $005DAF03  TCUSTOMEDIT__WNDPROC,  line 528 of ./include/customedit.inc
  $006525CF  DELIVERMESSAGE,  line 112 of lclmessageglue.pas
  $0059B5BD  TWINDOWPROCHELPER__DOWINDOWPROC,  line 2515 of win32callback.inc
  $0059BC8B  WINDOWPROC,  line 2677 of win32callback.inc
  $006491ED  GROUPBOXWINDOWPROC,  line 576 of win32wsstdctrls.pp
  $75E96238
  $75E968EA
  $75E9CD1A
  $75E9CD81
  $72596508
=======================================================================================       

//Na segunda linha mostra o nome do form, o evento, a linha do erro e o nome da unit onde ocorreu o erro.

Muito bom, brigadão EMBarbosa, perfeito!!!

 

Share this post


Link to post
Share on other sites

Obrigado!

No teu caso você está programando no lazaruz, FPC, eu estou programando no Delphi, daí não encontrei, parece que não tem na verdade para o Delphi, somente solução de terceiros =/

Share this post


Link to post
Share on other sites
58 minutos atrás, qqqoq disse:

Obrigado!

No teu caso você está programando no lazaruz, FPC, eu estou programando no Delphi, daí não encontrei, parece que não tem na verdade para o Delphi, somente solução de terceiros =/

Com a JCL é possível fazer isso. Tem artigos na internet.

  • Like 1

[]'s

Consultor SAC ACBr

Elton
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...