Suggested addition to Errsysw.prg

Suggested addition to Errsysw.prg

Postby Roger Seiler » Sat Jun 28, 2008 3:48 pm

Below is an addition that I made to my version of Errsysw.prg that I find very helpful. This addition retains info from any prior error.log, adding it to the end of the current cErrorlog, until the error.log file exceeds 50 K in size. If over 50 K, then just the most recent 5k chars of info are retained, and the file builds again.

This prevents losing important error info in a situation where different errors occur in quick succession before you have a chance to debug the first errors in the sequence. Especially important where a customer fails to tell you about an earlier error before they crash the app with something else.

Here it is, to be added just above existing Errsysw.prg comment,
"// Generates a file with an Error Log "

Code: Select all  Expand view
   
   // If an Error.log already exists, add it to bottom of cErrorLog.
   // Added this to retain prior error messages up to limit of 25k...
   IF FILE("Error.log")
      cText := MEMOREAD("Error.log")
      cText := CRLF+CRLF+REPLICATE("*",50)+ ;
               CRLF+REPLICATE("*",50)+CRLF+CRLF+cText
      IF LEN(cText) < 50000
         cErrorLog += cText
      ELSE
         cErrorLog += SUBSTR(cText,1,5000)
      ENDIF
   ENDIF

   // Generates a file with an Error Log

   BEGIN SEQUENCE  // [ continue with existing PRG code... ]



- Roger
User avatar
Roger Seiler
 
Posts: 223
Joined: Thu Dec 01, 2005 3:34 pm
Location: Nyack, New York, USA

Postby Roger Seiler » Sat Jun 28, 2008 3:52 pm

Forgot to mention that cText := "" is declared as a local at the beginning of the function.

- Roger
User avatar
Roger Seiler
 
Posts: 223
Joined: Thu Dec 01, 2005 3:34 pm
Location: Nyack, New York, USA

Postby Roger Seiler » Sat Jun 28, 2008 4:17 pm

Just thought of a way to do this even better. As error.log file builds to more than 50k chars, instead of arbitrarily saving only the the most recent 5k chars from the prior error info, we can just cut out the oldest info equal to the size of the new cErrorlog. This minimizes the loss of useful prior error info.

So here it is again (to be inserted just above Memowrit() section)...

Code: Select all  Expand view
   LOCAL cText := ""   // declare at top of function

   // Insert the following in Errsysw.prg just before Memowrit() section...

   // If an Error.log already exists, add it to bottom of cErrorLog.
   // Added this to retain prior error messages up to limit of 25k...
   IF FILE("Error.log")
      cText := MEMOREAD("Error.log")
      cText := CRLF+CRLF+REPLICATE("*",50)+ ;
               CRLF+REPLICATE("*",50)+CRLF+CRLF+cText
      IF LEN(cText) < 50000
         cErrorLog += cText
      ELSE
         cErrorLog += SUBSTR(cText,1,LEN(cText)-LEN(cErrorLog))
      ENDIF
   ENDIF

   // Generates a file with an Error Log    [ existing comment ]

   BEGIN SEQUENCE  // [ continue with existing PRG code... ]


- Roger
User avatar
Roger Seiler
 
Posts: 223
Joined: Thu Dec 01, 2005 3:34 pm
Location: Nyack, New York, USA

Postby Roger Seiler » Sat Jun 28, 2008 6:39 pm

Geez! Every time I look at this, I see a slightly better way to do it. This version lets the error.log file build up to just 55k, and keeps it at that size as it adds new error text to the top while deleting old error text at the bottom. If you want to retain more error text, then just increase the error.log max size in two places from 55000 to whatever...

Code: Select all  Expand view
   LOCAL cText := ""   // declare at top of function

   // Insert the following in Errsysw.prg just before Memowrit() section...

   // If an Error.log already exists, add it to bottom of cErrorLog.
   // Added this to retain prior error messages up to limit of 55k...
   IF FILE("Error.log")
      cText := MEMOREAD("Error.log")
      cText := CRLF+CRLF+REPLICATE("*",50)+ ;
               CRLF+REPLICATE("*",50)+CRLF+CRLF+cText
      cErrorLog += cText
      IF LEN(cErrorLog) > 55000    // For 16 bits, must set limit at 35000
         cErrorLog := SUBSTR(cErrorLog, 1, 55000)  // For 16 bits, 35000
      ENDIF                                      // due to 64k limit.
   ENDIF

   // Generates a file with an Error Log    [ existing comment ]

   BEGIN SEQUENCE  // [ continue with existing PRG code... ]


- Roger
User avatar
Roger Seiler
 
Posts: 223
Joined: Thu Dec 01, 2005 3:34 pm
Location: Nyack, New York, USA

Some changes in ERRORSYSW.prg

Postby ukoenig » Sat Jun 28, 2008 6:46 pm

Hello Roger,

some month ago, there was a toppic, i added a few lines
because i needed error files with different timestamps :


Code: Select all  Expand view

....
....
cErrorLog += "   Dynamic memory consume :" + CRLF
cErrorLog += "      Actual  Value : " + Str( MemUsed() ) + " bytes" + CRLF
cErrorLog += "      Highest Value : " + Str( MemMax() ) + " bytes" + CRLF
// nSymNames() no longer returns a real value! 15/April/97
/*
cErrorLog += "   SYMBOLS segment" + CRLF
cErrorLog += "      " + LTrim( Str( nSymNames() ) ) + " SymbolNames:   " + ;
                   LTrim( Str( nSymNames() * 16 ) ) + " bytes"

// The changes :

// you can save max 10 Error-messages
// then it starts with 1 again
//  -------------------------        path of your EXE-file
c_dir := GetModuleFilename(GetInstance(),"YOUR_PROG.EXE" + CHR(0), 255)
c_pfad   := left ( c_dir, rat( "\", c_dir) -1 )
// c_pfad   = Path of application
cERR := ""
cERR1 := ""
n := 0
BEGIN SEQUENCE
   oOldError = ErrorBlock( { || DoBreak() } )

   // ------------- NEW --------------------------------------

   FOR i := 1 TO 11
       n++
       xxx := lTRIM(str(n))
       cERR   := c_pfad + "\ERROR_" + xxx + ".log"
       // deletes the old error.log`s
       // ---------------------------------
       IF n = 11
          cERR := c_pfad + "\ERROR_1.log"
          x := 1
          FOR x := 1 TO 10
               xxx := ltrim(str(x))
               cERR1 := "ERROR_" + xxx + ".log"
               DELETE FILE "&cERR1"
          NEXT   
          MemoWrit( "&cERR", cErrorLog )
          EXIT
       ELSE
          IF !FILE( "&cERR" )
               MemoWrit( "&cERR", cErrorLog )
               EXIT
          ENDIF
      ENDIF
NEXT
cERR3 := "ERROR_" + xxx + ".log"

// -------------------------------------------

END SEQUENCE
ErrorBlock( oOldError )



Best Regards
Uwe :lol:
Since 1995 ( the first release of FW 1.9 )
i work with FW.
If you have any questions about special functions, maybe i can help.
User avatar
ukoenig
 
Posts: 4043
Joined: Wed Dec 19, 2007 6:40 pm
Location: Germany

Postby Roger Seiler » Sun Jun 29, 2008 12:49 am

The reason I prefer to keep the error messages in one file instead of a separate file for each, is to make it easier for customers to email to me the error.log that I need. They don't want to have to figure out which ERRnnn.log file to send to me. It is just simpler this way, and the single file usually goes back to cover about the last 3 errors - usually all that I need.

- Roger
User avatar
Roger Seiler
 
Posts: 223
Joined: Thu Dec 01, 2005 3:34 pm
Location: Nyack, New York, USA

Postby Otto » Sun Jun 29, 2008 6:26 pm

Roger,
I think yours is a good idea.
Wouldn’t it be a good idea too to encode the file and also
give the file an other name maybe temp file.

I think it is not very clever to document an error in such a clear way.
You never know what people do with such files.
Otto
User avatar
Otto
 
Posts: 6328
Joined: Fri Oct 07, 2005 7:07 pm

Postby Roger Seiler » Tue Jul 01, 2008 1:31 pm

Otto,

Yes, the text could be encrypted. However, with my types of apps and the types of customers I'm working with, I haven't yet felt the need to do this. I don't seem to have any customers yet who are capable of understanding what the info in the error.log file means, much less what they might be able to do with it that could be against my interests. Thus I prefer to keep the process of getting the error.log info from the customer as simple as possible (and as complete as possible) so that I can solve any problem as quickly as possible.

- Roger
User avatar
Roger Seiler
 
Posts: 223
Joined: Thu Dec 01, 2005 3:34 pm
Location: Nyack, New York, USA

Postby Rochinha » Tue Jul 01, 2008 4:00 pm

Roger,

You can automate send error file,

I use Blat to this:
Code: Select all  Expand view
...
   // Generates a file with an Error Log

   BEGIN SEQUENCE
         oOldError = ErrorBlock( { || DoBreak() } )
         MemoWrit( "Error.log", cErrorLog )
   END SEQUENCE
   ErrorBlock( oOldError )

    /* PANTALLA DE CONTROL DEL ERROR */
    DEFINE FONT oFont NAME "Ms Sans Serif" SIZE 0, -10

    DEFINE DIALOG oDlg RESOURCE "dlgMSRel"
    REDEFINE SAY oSay VAR "O seguinte erro foi encontrado:"+CRLF+"    "+TiraErrLixo(ErrorMessage( e ))+CRLF+StackMessage ID  99 OF oDlg COLOR RGB(000,000,000),RGB(255,255,255)
    REDEFINE SAY oSay ID 100 OF oDlg COLOR RGB(255,255,255),RGB(000,000,000)

    REDEFINE BUTTON oBtn1 ID 1 OF oDlg ;
                 ACTION Blat( "Cliente: " + M->CL_NOME,;
                      "smtp.isp.com",;
                      M->CL_EMAIL,;
                      "YourEmail@isp.com",;
                      "***** System Error Message *****",;
                      "UserName",;
                      "UserPassword",;
                      "error.log" )
    REDEFINE BUTTON oBtn2 ID 2 OF oDlg ACTION oDlg:End()
    REDEFINE BUTTON oBtn3 ID 3 OF oDlg ACTION WAITRUN("NOTEPAD ERROR.LOG") NOBORDER
    REDEFINE BUTTON oBtn4 ID 4 OF oDlg ACTION ( lRet  := .t., oDlg:End() ) // Retry
    REDEFINE BUTTON oBtn5 ID 5 OF oDlg ACTION ( lRet  := .f., oDlg:End() ) // Default

    ACTIVATE DIALOG oDlg CENTERED ;
             ON INIT ( iif(e:CanRetry,oBtn4:Enable(),oBtn4:Disable()), ;
                       iif(e:CanDefault,oBtn4:Enable(),oBtn4:Disable()) )
    oFont:End()

    BEGIN SEQUENCE
        oOldError = ErrorBlock( { || DoBreak() } )

        /*  CONTROL PERSONALIZADO DE ERRORES */
        if !lIsDir( "ERRORES" )    //CREAR CARPETA DE ERRORES DEL PROGRAMA
           lMkDir( "ERRORES" )
        endif
...


Dialog .RC File:
Code: Select all  Expand view
dlgMSRel DIALOG 20, 28, 245, 138
STYLE 0x4L | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Mensagem de Erro"
FONT 8, "MS Sans Serif"
{
DEFPUSHBUTTON "&Não enviar", 2, 120, 121, 52, 14
PUSHBUTTON "&Enviar relatório de erros", 1, 4, 121, 114, 14
PUSHBUTTON "Clique aqui.", 3, 188, 96, 55, 14
PUSHBUTTON "&Denovo", 4, 173, 121, 34, 14, WS_DISABLED | WS_TABSTOP
PUSHBUTTON "&Padrão", 5, 209, 121, 34, 14, WS_DISABLED | WS_TABSTOP
LTEXT "Para visualizar os dados contidos neste relatório de erros.", -1, 5, 99, 181, 9
CONTROL "", 100, "static", SS_WHITERECT | WS_CHILD | WS_VISIBLE, -8, -1, 261, 30
ICON "icon_info", -1, 4, 3, 18, 20
LTEXT "Evento de detecção de erros", 99, 28, 3, 224, 24
LTEXT "O programa não responde.", -1, 4, 35, 247, 9
LTEXT "Informe este problema à 5Volution.", -1, 5, 52, 247, 9
LTEXT "Foi criado um relatório detalhando o erro ocorrido que voce pode nos enviar para ajudar a melhorar o 5Volution. Esse relatório será considerado confidencial e anônimo.", -1, 5, 66, 241, 29
GROUPBOX "", -1, -5, 25, 256, 93, BS_GROUPBOX
}


Blat function:
Code: Select all  Expand view
function blat( cbody ,;
               cserver ,;
               cto ,;
               cf ,;
               csubject ,;
               cu ,;
               cpw ,;
               cattach )
     BlatCMD := [ blat.txt] + ;
                [ -server ]   + alltrim(cserver) + ;
                [ -to ]       + alltrim(cto) + ;
                [ -f ]        + alltrim(cf) + ;
                [ -mailfrom ] + alltrim(cf) + ;
                [ -subject "] + alltrim(csubject) + ["] + ;
                [ -r ]        + ;
                [ -u ]        + alltrim(cu) + ;
                [ -pw ]       + alltrim(cpw) + ;
                [ -log "email.log" -debug ] + ;
                iif( empty( cAttach ),[],[ -attach "] + alltrim(cattach) + ["])
     cMacro="BLAT.EXE " + BlatCMD
     fErase( "email.log" )
     cBody := FormHtml( cSubject, cBody )
     memowrit( "blat.txt", cbody )
     //memowrit( "blat.bat", cMacro )
     WinExec( cMacro, 0 )
     if file( "blat.log" )
        BlatLOG := memoread( "email.log" )
        if "ERROR" $ Upper(BlatLOG)
            Mensagem( "Erro: arquivo de BLAT.LOG foi criado" )
            return .f.
        endif
     endif
     RETURN .T.

Function FormHtml( cSubject, cBody )
   Local cOpen := "", cClose := ""
   cHTML := ;
      '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"' + CRLF + ;
      '                      "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">' + CRLF + ;
      '<html>' + CRLF + ;
      '<head>' + CRLF + ;
      '   <title>' + cSubject + '</title>' + CRLF + ;
      '   <meta http-equiv="Content-Type"' + CRLF + ;
      '         content="text/html; charset=iso-8859-1">' + CRLF + ;
      '</head>' + CRLF + ;
      '<body>' + CRLF + ;
      cBody + CRLF + ;
      '</body>' + CRLF + ;
      '</html>'
   Return cOpen + cHTML + cClose


On error occurrency, this routine send the email with error.log to you.
Rochinha
 
Posts: 310
Joined: Sun Jan 08, 2006 10:09 pm
Location: Brasil - Sao Paulo

Postby MOISES » Tue Jul 01, 2008 7:51 pm

Antonio,

Why not to add this features to errosrsyw?.
Saludos / Regards,

FWH 20.04, Harbour 3.2.0 dev (r1909261630) y BCC 7.40
MOISES
 
Posts: 838
Joined: Wed Aug 22, 2007 10:09 am

Postby MOISES » Wed Jul 02, 2008 11:15 am

Hi,

For sending the email, I think it will be better to use MAPI.
Saludos / Regards,

FWH 20.04, Harbour 3.2.0 dev (r1909261630) y BCC 7.40
MOISES
 
Posts: 838
Joined: Wed Aug 22, 2007 10:09 am

Postby Roger Seiler » Thu Jul 03, 2008 12:18 pm

Rochinha,

Thank you! Great idea!

- Roger
User avatar
Roger Seiler
 
Posts: 223
Joined: Thu Dec 01, 2005 3:34 pm
Location: Nyack, New York, USA

Postby Rochinha » Thu Jul 03, 2008 1:17 pm

Roger,

Thanks too!

Moises,

I´m using Blat because MAPI fails with Outlook or Outlook 2000 security.

MAPI works fine with Eudora.

See more examples in http://www.fivetechsoft.com/forums/view ... blat+class
Rochinha
 
Posts: 310
Joined: Sun Jan 08, 2006 10:09 pm
Location: Brasil - Sao Paulo


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 70 guests