ErrorSys.Prg erweitern

Sonstiges (nicht kategorisierbar)

Moderator: Moderatoren

Benutzeravatar
Magic
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 343
Registriert: Mo, 11. Jul 2011 12:01

ErrorSys.Prg erweitern

Beitrag von Magic »

Hi,

ich würde gerne den Errorlog erweitern.
Dazu müsste ich (so weit wie ich es verstanden habe) die ErrorSys.PRG anpassen.

Frage 1:
Wenn ich sie erweitert habe, muss ich sie dann im jeden Projekt einzeln einbinden oder kann ich die "Standard" ErrorSys austauschen?

Frage 2:
In den Errorlog möchte ich 2 weiteren Infos reinschreiben.
Der Rechnernamen (oder die IP) und den User? Wie mache ich es?
Einfach die STATIC PROCEDURE ErrorLog( oError, nStackStart ) nach beliebigen erweitern?
Gruß,
Magic
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ErrorSys.Prg erweitern

Beitrag von brandelh »

zu 1.: Genau, du musst die ErrorLog.PRG ins Projekt aufnehmen, die erstellte OBJ Datei wird dann die Funktion der DLL ersetzten (Funktion mit gleichem Namen der EXE geht vor einer in einer DLL).
Ich kenne keinen weg die original DLL zu ändern ... außerdem gilt die ja für ALLE erstellen Programme.

zu 2.: hier ein Beispiel wie ich es erweitert habe:

Code: Alles auswählen

*************************************
* Standart Fehlerbehandlungsfunktion
*************************************
STATIC FUNCTION StandardEH( oError )
   ...
   Static nFehler_Stack := 0                    // HB *** so kennzeichne ich, was ICH geändert habe ... es soll ja mal neue Versionen geben ;-)
   if nFehler_Stack > 5
      quit                                              // nach 5 Aufrufen der Funktion wird diese beendet, das verhindert eine FATAL bzw. endlose Fehlermeldungen bei recursiven Fehlern !
   endif
   ...
   nFehler_Stack++                              // HB

   /* Keine Standardkorrektur definiert: Erzeuge Fehlermeldung */
   cMessage := ErrorMessage( oError )
   ...
   CASE aOptions[i] == EHS_EXIT_WITH_LOG
           ErrorLog( oError, 2, nFehler_Stack )     // HB
   ...
************************************************
STATIC PROCEDURE ErrorLog( oError, nStackStart, nFehler_Stack ) // HB
   ...
   SET ALTERNATE TO (cErrorLog) Additive       // HB - ich will ein Fehlerprotokoll aller aufgetretenen Fehler
   ?
   ? Replicate( "-", 78 )
   ? EHS_ERROR_LOG_OF +'"'+ appName(.T.) +'"'+ EHS_DATE, Date(), Time(), "***", ntrim(nFehler_Stack) // HB - bei einer Liste muss man deutliche Trenner haben
   ? "Programm:  "+SetAppWindow():ProgName             // HB
   ? "Version:   "+SetAppWindow():ProgVersion+;        // HB *** das sind eigene Instanzvariablen des Hauptfensters, man könnte auch Public oder ein Application-Objekt verwenden.
      "     vom: "+SetAppWindow():ProgFreiDatum        // HB
   ? "Rechner:   "+netname()                           // HB
   ? "Userinfo:  "+SetAppWindow():UserInfo             // HB *** je nach Programm ...
   * hier könnte weitere Infos stehen                  // HB
   ?
   ? EHS_XPP_VERSION , Version()+"."+Version(3)
   ? EHS_OS_VERSION  , Os()
   ? Replicate( "-", 78 )
Gruß
Hubert
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Re: ErrorSys.Prg erweitern

Beitrag von Rudolf »

Hallo,
einfach die STATIC PROCEDURE ErrorLog erweitern und errorsys.obj zu den Projekten dazulinken.
Grüße
Rudolf

Beispiel:

Code: Alles auswählen

************************************************
STATIC PROCEDURE ErrorLog( oError, nStackStart )
*
*  Creates a string with the important Informations
*  from the error object
************************************************
   LOCAL i:=0, bError := ErrorBlock( {|e| Break(e)} )
   LOCAL cErrorLog
   LOCAL cExtension:= "LOG"
   LOCAL lPrint, lConsole, cAlternate, lAlternate, lExtra
   /* Save current printer related settings, turn printer off */
   lPrint     := Set( _SET_PRINTER )
   lConsole   := Set( _SET_CONSOLE )
   cAlternate := Set( _SET_ALTFILE )
   lAlternate := Set( _SET_ALTERNATE )
   lExtra     := Set( _SET_EXTRA, .F. )

   SET PRINTER OFF
   SET CONSOLE ON

   IF SetAppWindow() == NIL ;
     .OR. .NOT. SetAppWindow():isDerivedFrom( RootCrt() )
      SET CONSOLE OFF
   ENDIF

   /* Trap errors that might occur while opening the ALTERNATE file */
   DO WHILE .T.
      cErrorLog := EHS_ERRORLOG + "." + cExtension
      BEGIN SEQUENCE
        SET ALTERNATE TO (cErrorLog)
        SET ALTERNATE ON
      RECOVER
        /*
         * ALTERNATE file could not be opened:
         * try other filename
         */
        cExtension := PadL(++i,3,"0")
        IF i > 999
           IF AppType() <> APPTYPE_PM
              TONE(660,5)
              ? EHS_LOG_OPEN_FAILED
              IF !Set( _SET_CONSOLE )
                  OutErr( CHR(10)+CHR(13) + EHS_LOG_OPEN_FAILED )
              ENDIF
           ELSE
              MsgBox( EHS_LOG_OPEN_FAILED )
           ENDIF
           ErrorLevel(1)
           QUIT
        ENDIF
        LOOP
      END SEQUENCE
      EXIT
   ENDDO

   ErrorBlock( bError )

   ? Replicate( "-", 78 )
   ? EHS_ERROR_LOG_OF +'"'+ appName(.T.) +'"'+ EHS_DATE, Date(), Time()
   ?
   ? EHS_XPP_VERSION , Version()+"."+Version(3)
   ? EHS_OS_VERSION  , Os()
   ? Replicate( "-", 78 )
   ? "oError:args         :"
   IF Valtype(oError:Args)=="A"
      AEval( oError:Args, ;
             {|x,y| Qout( Space(9),"-> VALTYPE:", y:=Valtype(x) )  , ;
                     IIf( y=="O", QQout( " CLASS:", x:className() ), ;
                                  QQout( " VALUE:", Var2Char(x) ) ) } )
   ELSE
      Qout( Space(10),"-> NIL" )
   ENDIF

   ? "oError:canDefault   :" , oError:canDefault
   ? "oError:canRetry     :" , oError:canRetry
   ? "oError:canSubstitute:" , oError:canSubstitute
   ? "oError:cargo        :" , oError:cargo
   ? "oError:description  :" , oError:description
   ? "oError:filename     :" , oError:filename
   ? "oError:genCode      :" , oError:genCode
   ? "oError:operation    :" , oError:operation
   ? "oError:osCode       :" , oError:osCode
   ? "oError:severity     :" , oError:severity
   ? "oError:subCode      :" , oError:subCode
   ? "oError:subSystem    :" , oError:subSystem
   ? "oError:thread       :" , oError:thread
   ? "oError:tries        :" , oError:tries

   ? Replicate( "-", 78 )
   ? "CALLSTACK:"
   ? Replicate( "-", 78 )

   i := nStackStart
   DO WHILE ! Empty( ProcName(++i) )
      ? EHS_CALLED_FROM, Trim( ProcName(i) )   + "(" + ;
                 LTrim( Str( ProcLine(i) ) ) + ")"
   ENDDO
   *********************************** EXTENDED LOG ***************************************************

     aWSL := WorkSpaceList()
     nWSL := LEN( aWSL )
     ? "WorkSpaceList       :", ""
     FOR j = 1 TO nWSL

          ? "------------ Alias :" + aWSL[ j ] + "--------------------"
          ? "Recno() = " + (aWSL[ j ])->(Ltrim(Str(Recno(),10)))
          ? "lastrec() = " + (aWSL[ j ])->(Ltrim(Str(lastrec(),10)))
          ? "Eof() = " + iif((aWSL[ j ])->(Eof()),"TRUE","FALSE") + "  Bof() = " + iif((aWSL[ j ])->(Bof()),"TRUE","FALSE")
          ? "Scope Top = " + var2char((aWSL[ j ])->(dc_setscope(0)))
          ? "Scope Bottom = " + var2char((aWSL[ j ])->(dc_setscope(1)))
          ? "Focus = " + (aWSL[ j ])->(OrdSetFocus())
          nOrders := (aWSL[ j ])->(DbInfo( DBO_ORDERS ))
          for z := 1 to nOrders
               (aWSL[ j ])->(ordsetfocus(z))
               ? "Order " + ltrim(str(z)) + " Indexkey = " + (aWSL[ j ])->(indexkey())
          next z
          ? "------------- locked records -------------------------------"
          aLock := ( aWSL[ j ] )->( DBRLOCKLIST() )
          nLock := LEN( aLock )
          IF nLock > 0
          FOR k = 1 TO nLock
               IF k = 1
                    ?? " : Record No. " + LTRIM( STR( aLock[ k ] ) )
               ELSE
                    ?? "," + LTRIM( STR( aLock[ k ] ) )
               ENDIF
          NEXT
          ?? " locked"
          ELSE
          ?? " : NO Record locked"
          ENDIF
     NEXT

   ******************************************************************************************************
   SET ALTERNATE TO
   SET ALTERNATE OFF

   IF AppType() <> APPTYPE_PM
      TONE(660,5)
      ? EHS_LOG_WRITTEN_TO(cErrorLog)
      IF !Set( _SET_CONSOLE )
          OutErr( CHR(10)+CHR(13) + EHS_LOG_WRITTEN_TO(cErrorLog) )
      ENDIF
   ELSE
      //MsgBox( EHS_LOG_WRITTEN_TO(cErrorLog)  )           
   ENDIF

   /* Restore previous settings */
   Set( _SET_PRINTER,   lPrint)
   Set( _SET_CONSOLE,   lConsole)
   Set( _SET_ALTFILE,   cAlternate)
   Set( _SET_ALTERNATE, lAlternate)
   Set( _SET_EXTRA,     lExtra)

RETURN

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9357
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: ErrorSys.Prg erweitern

Beitrag von Tom »

Das ErrorSys steckt in der XbpSys.DLL. Wenn Du eine eigene linkst, wird diese ignoriert.

Generell ist Vorsicht geboten, wenn das eigene Errorhandling zu "intensiv" arbeitet, also beispielsweise auf Tabellen zugreifen oder zu installierende ActiveX-Komponenten verwenden will. Das kann im Fehlerfall zu einem "Error within the errorhandling" führen, wenn beispielsweise Netzlaufwerke nicht gefunden werden. Solche Funktionalitäten sollten dann alles intensiv prüfen oder in Sequenzen gekapselt werden. Sonst kriegt man falsche Fehler. :wink:

Den Computernamen erhält man durch eine einfache Abfrage der Environment-Variable "Computername": GetEnv("Computername"). Den Namen des angemeldeten Benutzers erhält man über die API-Funktion "GetUserNameA" aus "ADVAPI32.DLL".
Herzlich,
Tom
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ErrorSys.Prg erweitern

Beitrag von brandelh »

und errorsys.obj zu den Projekten dazulinken.
die offizielle Vorgehensweise bei PBuild ist, dass man die PRG einträgt ...

Code: Alles auswählen

[MDIW32.EXE]
    ...
    ERRORSYS.PRG
und mit PBUILD /G den Rest erzeugen lässt ...

Code: Alles auswählen

[MDIW32.EXE]
// $START-AUTODEPEND
    ...
    ERRORSYS.OBJ
// $STOP-AUTODEPEND
    ...
    ERRORSYS.PRG
Selbst falls die neue XppError.PRG für alle Projekte benutzt werden soll, spart man sich jede Menge Ärger, wenn man die Projektdatei richtig mit der PRG bestückt und vervollständigen läßt.
Ich habe nie alle Programme gleichzeitig auf neue Xbase++ Versionen umgestellt und so auf diese Weise wird immer die neueste PRG Datei mit dem richtigen Compiler verwendet.
Gruß
Hubert
Benutzeravatar
Magic
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 343
Registriert: Mo, 11. Jul 2011 12:01

Re: ErrorSys.Prg erweitern

Beitrag von Magic »

Super & vielen Dank für Eure Express-Hinweise :!:
Gruß,
Magic
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9357
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: ErrorSys.Prg erweitern

Beitrag von Tom »

Falls Du beispielsweise Fehler in einer Tabelle protokollieren möchtest, aber natürlich auch den Fall ausschließen willst, dass überhaupt keine Tabellen sichtbar sind oder dieses Protokollsystem von einem Fehler betroffen sind, wäre derlei das Mittel der Wahl:

Code: Alles auswählen

STATIC PROC SaveErrors(cText)
LOCAL bError := ErrorBlock({|o|Break(o)}) // aktueller Error-Codeblock wird in "bError" gespeichert, Break() wird als neuer Error-Codeblock etabliert
BEGIN SEQUENCE
USE ErrorProto NEW
APPEND BLANK
REPLACE datum WITH Date()
REPLACE zeit WITH Time()
REPLACE benutzer ....
CLOSE
END SEQUENCE
ErrorBlock(bError) // alten Error-Codeblock wieder aktivieren
RETURN
Statt die Sequenz im Fehlerfall mit "Break" zu beenden, könnte der Fehler-Codeblock auch auf eine Funktion verweisen, die den Fehlertext "cText" alternativ in eine Textdatei schreibt oder so. Mit dieser Sequenz werden alle Fehler abgefangen, die mit der Protokolldatei auftreten könnten, also nicht nur ihr Fehlen, sondern auch Korruptionen und ähnliches, wodurch diese Systematik besser wäre als Kombinationen aus "File()" und "NetErr()" usw.
Herzlich,
Tom
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14651
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: ErrorSys.Prg erweitern

Beitrag von Jan »

Ergänzend zu Tom: Ich trage ebenfalls den Namend es Rechners und den Anmeldenamen in die xpperror ein. Aber beides über getEnv():

Code: Alles auswählen

   cMeldung += "Computername        : " + GETenv("COMPUTERNAME") + crlf
   cMeldung += "Anmeldename          : " + GETenv("USERNAME") + crlf
Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9357
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: ErrorSys.Prg erweitern

Beitrag von Tom »

@Jan: Es geht eine Menge über das "Environment". Einfach mal ein Kommandofenster ("DOS-Prompt") öffnen und "SET" eingeben. Alles, was man da sieht, kann man über GetEnv() abfragen. Aber, Vorsicht - man kann es eben auch setzen (ab Windows 7 allerdings etwas komplizierter als vorher). Eine Environment-Variable reflektiert nicht unbedingt den erwarteten Wert. Mir ist schon begegnet, dass da herumgefrickelt wird, um beispielsweise Server zu täuschen, während der tatsächliche Benutzername ein anderer war. Deshalb bevorzuge ich die API-Funktionen.

Grundsätzlich. Man sollte im Fehlersystem so viele Informationen wie nötig und möglich aufbereiten, also alles, was beim First-Level-Support, aber auch darüber hinaus hilfreich sein kann. Hubert hat das mit seinen Funktionen, die alle geöffneten Tabellen, u.U. gesetzte Scopes, Datensatzzeiger geöffnete Indexdateien, Indexausdrücke u.v.a.m. auflisten, bereits angedeutet. Wir ergänzen das um folgende weitere Informationen:

- einen Screenshot
- Versionsnummern aller DLLs, die zur Applikation gehören und/oder von ihr geladen wurden, auch bei Laufzeit-DLLs von Alaska und Drittanbietern (dort auch interne Versionsnummern, falls verfügbar)
- Informationen über alle Threads, die vom Programm gestartet wurden und noch laufen
- Stati der systembezogenen Voreinstellungen der Applikation, interne Rechte des angemeldeten Benutzers
- wichtige Werte einiger Set()-Einstellungen (_SET_PATH, _SET_DEFAULT, _SET_EPOCH usw.)
- eingestellter Drucker
- Jobnummern und DLL-Handles zu Reportgeneratoren und Zusatzprodukten
- Nationalitäteneinstellung des Betriebssystems (eine sehr originelle Fehlerquelle)
- OS-Version
- Datum des letzten Applikationsupdates
- natürlich Versionsnummer der App und Versionsnummer der Datenbankstruktur
usw.

Außerdem enthält das Log (das über L&L optisch aufbereitet wird und gedruckt, gefaxt und/oder per Mail gesandt werden kann, zudem kann es von der App per SOAP direkt auf unseren Server hochgeladen werden) einen Identifier, der sich aus Versionsnummer der App, der Zeilennummer der letzten Funktion aus unserem (!) Quellcode (also nix etwa aus dem Quellcode von XbpBrowse) und der Fehlerbeschreibung zusammensetzt. Dieser Identifier wird, wenn das Log auf den Server geladen wird, automatisch in eine Tabelle eingetragen, sofern es den Eintrag noch nicht gibt. Ansonsten wird die Tabelle manuell gepflegt. Sie enthält neben diesem Identifier eine Erklärung zum Fehler und zur Ursache, mögliche Workarounds oder Fehlerbehebungsmechanismen und bei Programm(ier)fehlern Hinweise auf die Version, in der dieser Fehler behoben ist. Das Verwaltungsssystem hierzu findet auch ähnliche Fehler, so dass Zusammenhänge hergestellt werden können (da Dateifehler ja meistens versionsunabhängig sind). All das erleichtert unseren Support sehr. Wir bauen es derzeit noch weiter aus, um Kunden individuell beispielsweise über bekannte Probleme in bei ihnen installierten Versionen zu informieren, aber auch über allgemein verfügbare Neuerungen oder individuelle Anpassungen, die inzwischen fertiggestellt wurden.

Nur so als Denkanstoß. :wink:
Herzlich,
Tom
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14651
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: ErrorSys.Prg erweitern

Beitrag von Jan »

Hallo Tom,

was meinst Du denn, woher ich die beiden Variablen habe ;-) Wenn man ein mal das Prinzip verstanden hat, dann kann man dadurch eine Menge Infos rausziehen, für die man ansonsten irre komplizierte Wege gehen müßte.

Aber Danke für den Hinweis auf den gefakten Anmeldenamen. Das kannte ich noch nicht. Ist aber in den Fällen, wo ich damit arbeite, auch egal.

Du schreibst da ja wirklich eine Menge Infos in Deine errorlog. Viele davon verwende ich auch, andere sind eine gute Idee, manche sind bei mir überflüssig. Ich habe meine Standard-Errorlog übrigens ebenfalls so erweitert, das automatisch eine Mail (per blat) an den Support geht. Bei Programmen an den Endkunden natürlich nur nach vorheriger Rückfrage beim Kunden, bei Inhouse-Lösungen ohen jede Rückmeldung. Das hilft wirklich enorm.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ErrorSys.Prg erweitern

Beitrag von brandelh »

Ich nutze den Anmeldenamen mit getenv(), so kann ich lokal beim Testen mit einer CMD den Anmeldenamen vorgeben, dessen Rechte ich gerade testen will.
Früher habe ich über diesen auch die Zugehörigkeit der Abteilung / Standort ermittelt und automatisch die Adressen vorgegeben.
Dafür war das Ändern des SET Wertes klasse, hinzu kommt dass ich damals keine Ahnung von der Abfrage der API gehabt hätte 8)
Inhause Entwicklung und die Programmvorhaltung auf Citrixservern begrenzen natürlich die Gefahren enorm.

Wenn bei TOMs Programm so an die Anmeldung des Chefarztes kommen würde ... :oops:

Also immer schön nachdenken bevor man was macht ;-)
Gruß
Hubert
Benutzeravatar
Magic
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 343
Registriert: Mo, 11. Jul 2011 12:01

Re: ErrorSys.Prg erweitern

Beitrag von Magic »

Bin gerade dabei die ersten (einfachen) Änderungen zu implementieren.
Im ersten Schritt will ich ja nicht wildes, sondern lediglich ein paar Informationen um besser eingrenzen zu können bei welchem User ein Fehler aufgetreten ist. Das ist für mich wichtig, denn bei uns werden die Xbase-Anwendungen vom Server gestartet um im Fehlerfall auch der Errorlog auf dem Server abgelegt, bzw. eine vorhandene Errorlog Datei überschrieben.

Jetzt habe ich mir etwas geschrieben (im VBS), dass mir evtl. vorhandene Errorlogs per Mail zuschickt, somit werde ich dann automatisch über mögliche Fehler informiert, auch wenn der Benutzer selbst es nicht tut(!).

Das funktioniert auch ganz zuverlässig, nur fehlt mir jetzt noch die Info bei wem / auf welchen Rechner der Fehler produziert wurde.
Dann habe ich erst einmal eine schlichte aber automatische und zeitnahe Fehlerbenachrichtigung.

Übrigens, das ganze aufgrund des Posts: Error 5041 "The requested object was not found".
Gruß,
Magic
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ErrorSys.Prg erweitern

Beitrag von brandelh »

Zu beachten ist, dass der eigentliche Fehler ab und zu von jemandem verursacht wird (z.b. fehlerhafte Plausiprüfung), aber erst bei einem anderen Anwender zum Runtimefehler führt.

Ansonsten kann man den angemeldeten USER und den Rechnernamen aus den SET Werten ermitteln:
User: USERNAME
Rechner: COMPUTERNAME
Angenommen der Inhalt von COMPUTERNAME ist ABC und LOGONSERVER=\\ABC, dann liegt eine LOKALE Anmeldung vor ;-)
oder auch wenn USERDOMAIN gleich dem COMPUTERNAME ist.

Über den Inhalt kann man auch Citrix / TS Sitzungen erkennen, die genaue Syntax musst du aber hier suchen (die weiß ich nicht aus dem Kopf).
Gruß
Hubert
Daniel

Re: ErrorSys.Prg erweitern

Beitrag von Daniel »

Zum Funktionieren der Errorsys noch eine Frage.
In der STATIC FUNC StandardEH( oError):
- Was ist der Befehl, den letzten Befehl im Programm zu wiederholen (RETRY)?
- Welcher Befehl (falls nötig) führt zu der bekannten ALERTBOX ?
- was bewirkt RETURN(.T.) / RETURN(.F.)

Ich habe die Doku abgesucht, aber keine Angaben dazu gefunden.
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: ErrorSys.Prg erweitern

Beitrag von AUGE_OHR »

Magic hat geschrieben:Frage 1:
Wenn ich sie erweitert habe, muss ich sie dann im jeden Projekt einzeln einbinden oder kann ich die "Standard" ErrorSys austauschen?
wie Tom schon sagte steckt die ErrorSys in der XbpSys.DLL.
wenn es für alle deine Projekte sein soll kannst du C:\ALASKA\XPPW32\Source\SYS\ErrorSys.prg direkt bearbeiten
und dir eine neue XbpSys.DLL erstellen mit C:\ALASKA\XPPW32\Source\dll\PROJECT.XPJ

zu den gezeigten Erweiterungen würde ich noch ALIAS() und ThreadInfo() dazu nehmen.
gruss by OHR
Jimmy
DelUser01

Re: ErrorSys.Prg erweitern

Beitrag von DelUser01 »

Hallo

Baue mein zentrales ErrorSys.prg seit längerem ständig weiter aus, dass ALLE Programmeinstellungen, DBEs, PC-Info, Netzwerk-Info, DB und und und im LOG stehen.
Das ErorSys nutze ich so auch als Status-Info, dafür habe ich in jeder App einen Button.
(Header: ERRORLOG -> SYSTEMINFO)
Habe gerade Mal ein LOG abgerufen, hat 550 Zeilen. Kann je nach geöffneten DBFs und NTX viel größer oder kleiner sein.
Man braucht aber für die meisten (Programmierer-) Fehler den größten Teil der Infos nicht...
bei komplizierten Fehler möchte ich das nicht missen.
Benutzeravatar
Hans Zethofer
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 278
Registriert: Fr, 27. Jan 2006 8:29
Wohnort: 2700 Wiener Neustadt
Hat sich bedankt: 1 Mal
Kontaktdaten:

Re: ErrorSys.Prg erweitern

Beitrag von Hans Zethofer »

Der Aufbau deines ERROR.PRG würde mich interessieren :wink:
was du da noch alles hineingepackt hast. :idea:

Programm-Infos zur Laufzeit oder beim Absturz sind immer interessant für die Analyse
_____________
lg
Hans
DelUser01

Re: ErrorSys.Prg erweitern

Beitrag von DelUser01 »

Hallo Hans

hier ein Beispiel eines LOGs. Am besten kopieren und in einem Editor mit einem fixed Font anschauen. Den Source stelle ich bereit.

Code: Alles auswählen

--------------------------------------------------------------------------------
S Y S T E M I N F O
--------------------------------------------------------------------------------
Datum: 10.11.2014
Uhrzeit: 23:15:39
EXE-Filename: C:\gs\GSP1.EXE
Versions-Nr.: x11f
Update-Datum: 08.11.2014
Beta-Version: nein
Copyright: (c) 1990-2014 Gentner IT Service GmbH, Roland Gentner , all rights reserved
Serien-Nr.: 901
Firma: Heinz Fritz Kunststoffverarbeitung
Computername: GS28
Logonserver: \\DC2
Userdomain: RGS
Username: roland
Xbase++ VERSION()(n): Xbase++ (R) Version 1.90 /1: 1 /2: 90 /3: 355
Betriebssystem OS(): Windows 8 06.02 Build 09200 / WIN32 / WINNT / WIN8 / Windows 8 / 06.02.9200 / 
Win7/8/7o8 Erkennung: nein / ja   / ja  
Prozessor Bit-Version: 64bit (x64)
GsSysIs64Bit(): ja  
GsCpuSmpGetCpuNr(): 6
GsCpuGetNrOfProcessors(): 6
Window Handle Main_oCrt():getHWND():  3409960
Window Handle GsNumTexKo():  3409960
MainWebMode(): nein
Modul (Menu4PrgNr): P1STWER1UE
--------------------------------------------------------------------------------
S E T U P
MainTitel(): 1990-2014
MainVnr(): x11f
dcGsUpDate: 08.11.2014
MainPrgHeader(): PlexiPedia
MainUpdateManUpdNr(): 0
MainUpdateGetLocalNr(F): 0
MainUpdateGetServerNr(F): 0
MainComputerName(): gs28
MainFactoryName(): Heinz Fritz Kunststoffverarbeitung
MainSnrNr(): 901
MainUsrName(): ROLAND
CurDrive(): c
CurDir(): temp\GS
GsTempPath(): c:\temp
GsTempPathGs(): c:\temp\GS\
MainLogFile(): X:\HFP1\p1\GSP1_20141110_230755_8327525_1.log
MainExeFile(): C:\gs\GSP1.EXE
MainIniFile(): V:\FIRMAHFG1\GSp1.INI
MainDebugMode(): nein
MainTestMode(): nein
MainTestModePathReplace(): 0
MainTestModeValReplace(): 0
Test-Referenz: \P1-TEST\
MainPfSys(): X:\HFP1\p1\
MainPfPrv(): V:\FIRMAHFG1\
MainPfDat(): X:\HFP1\p1\
MainPfLog(): w:\log\
MainAutoQuit(): nein
--------------------------------------------------------------------------------
P R O B L E M B E S C H R E I B U N G
(01)  
--------------------------------------------------------------------------------
Z U S A T Z I N F O
GsErrorVar(): 
--------------------------------------------------------------------------------
C A L L S T A C K
 1 GSERRORCALLSTACK(1381)
 2 GSERRORWRITELOG(535)
 3 GSINFOLOG(226)
 4 (B)P1MENU(327)
 5 GSUSRINEVENT(828)
 6 GSGUIMSGEVENT(5671)
 7 GSGUIMSGWIN(5484)
 8 GSERRORHANDLER(165)
 9 (B)MAINAPPSYS(2885)
10 P1STWER1UEPOSITIONINGDBS(595)
11 P1STWER1UERECO(517)
12 GSUBGOMODUL(153)
13 GSUBRANG2(556)
14 GSUBSHOW1(69)
15 P1STWER1UEHEAD(476)
16 P1STWER1UE(113)
17 (B)P1MENU(304)
18 MENU4LOOP(733)
--------------------------------------------------------------------------------
A L A R M
Alarm: nein
MainAlarm(): 0
--------------------------------------------------------------------------------
E R R O R B L O C K
ErrorBlock(): { | e | Break( e ) }
ErrorLastErrBlk(): { | e | Break( e ) }
GsErrorLastErrObj(): Error
--------------------------------------------------------------------------------
D B E
MainAdsIp(): 172.29.59.5
MainAdsHost(): GSSRV3
MainLWtoUNC(): .T.
MainSetPathAndShortDbName(): .F.
GsCfgDriveMapStat(): K => \\GSSRV3\ADRESSEN => \\172.29.59.5\ADRESSEN
GsCfgDriveMapStat(): L => \\GSSRV3\ARTIKEL => \\172.29.59.5\ARTIKEL
GsCfgDriveMapStat(): M => \\GSSRV3\ENTWICKLUNG => \\172.29.59.5\ENTWICKLUNG
GsCfgDriveMapStat(): O => \\GSSRV3\INHAGRO => \\172.29.59.5\INHAGRO
GsCfgDriveMapStat(): P => \\GSSRV3\PRODUKTION => \\172.29.59.5\PRODUKTION
GsCfgDriveMapStat(): Q => \\GSSRV3\SOFTWARE => \\172.29.59.5\SOFTWARE
GsCfgDriveMapStat(): S => \\GSSRV3\SICHERUNG => \\172.29.59.5\SICHERUNG
GsCfgDriveMapStat(): W => \\GSSRV3\DATENAUSTAUSCH => \\172.29.59.5\DATENAUSTAUSCH
GsCfgDriveMapStat(): X => \\GSSRV3\VERWALTUNG => \\172.29.59.5\VERWALTUNG
GsCfgDriveMapStat(): V => \\DC2\ROLAND => \\DC2\ROLAND
--------------------------------------------------------------------------------
A D S D B E
DbeSetDefault: ADSDBE
ADS gefunden (O): ja
oDS:IsConnected(): ja
use ADS: ja
ADS is active: ja
Connected Threads: 1
Connection String: DBE=ADSDBE;SERVER=\\172.29.59.5:9889\verwaltung
MainAdsPort(): 9889
ADS-Drive: X
MainAdsMaxSpeedActive(): .T.
MainAdsDacVar() ArrPos 1: {1, dacSession, "DBE=ADSDBE;SERVER=\\172.29.59.5:9889\verwaltung"}
oDS:GetLastError() Nr: 0
oDS:GetMessage: 
--------------------------------------------------------------------------------
T H R E A D L I S T
this ThreadID(): 1
{ nThreadID , nHandle , nProcLine , cProcName , oOjectName }
Thread: {1, 700, 1436, "GSERRORTHREADALL", thread}
Thread: {3, 1540, 181, "MXPRINTSCREEN:EXECUTE", MxPrintScreen}
--------------------------------------------------------------------------------
P R O G R A M M W I N D O W S :   M A S T E R / S L A V E
MainPrgSlave(): N
MainPrgMaster(): N
MainDbSyMasterRec(): 0
MainDbSyRec(): 1
MainWinAddSlaveUpd(): N
MainWinAddLink(): N
MainUseNewWinLinkHelp(): J
MainNewWinOffsetXY(): {0, 0}
MainWinSetSyVar(): J
MainPrgMaster Handle GsWinPar10Hwnd():  0
MainPrgMaster AL_SY->HWND:  0
AL_SY->WINADDMAST:  0
AL_SY->WINADDHELP: N
MainF2Win(): N
--------------------------------------------------------------------------------
S T A R T P A R A M E T E R
MainPar1(): V:\FIRMAHFG1\GSP1.INI
MainPar2(): 
MainPar3(): 
MainPar4(): 
MainPar5(): 
MainPar6(): 
MainPar7(): 
MainPar8(): 
MainPar9(): 
MainPar9b(): 
MainPar10(): 
MainPar11(): 
--------------------------------------------------------------------------------
L A S T   H A N D L E E V E N T
MainLastCrtHandleEventVar()[1] = self: XbpCrt     Object created
MainLastCrtHandleEventVar()[2] = oXbpBaseCrt: XbpCrt     Object created
MainLastCrtHandleEventVar()[3] = nEvent: 1048598     xbeM_Motion
MainLastCrtHandleEventVar()[4] = mp1 Modify: {0, 45}
MainLastCrtHandleEventVar()[5] = mp2: NIL
MainLastCrtHandleEventVar()[6] = mp1 Origin: {0, 45}
--------------------------------------------------------------------------------
E V E N T
LastAppEvent(): 1048610
NextAppEvent(): 1048963
--------------------------------------------------------------------------------
T E M P F I L E
Len( GsTempFileServVar() ) 0
Len( GsTempFileLocVar() ) 24
--------------------------------------------------------------------------------
A L _ S Y
AL_SY geoeffnet: J
LastRec(): 1
RecNo(): 1 
MainDbSyMasterRec(): 0
MainDbSyRec(): 1
DbRLock() auf Record-Nr: 1
--------------------------------------------------------------------------------
S E L E C T
Alias(): AL_SX1
RecNo(): 104
DbInfo(DBO_FILENAME): \\172.29.59.5\VERWALTUNG\HFP1\P1\P1SX1001.DBF
OrdBagName(OrdNumber()): P1SX1001.NTX
DbInfo(DBO_ALIAS): AL_SX1
DbInfo(DBO_RELATIONS): 0
DbInfo(DBO_ORDERS): 5
DbInfo(DBO_SHARED): J
DbInfo(DBO_DBENAME): ADSDBE
DbRLock() auf Record-Nr: kein Rekord gelockt
--------------------------------------------------------------------------------
G S W A R T E N
ThreadID(): 1
ValType( GsWartenVar()[1] ): O
GsWartenVar()[1]:status():          1
ValType( GsWartenVar()[2] ): N
--------------------------------------------------------------------------------
F T P
MainFtpIniVariante(): 2
MainFtpUseVariante(): 0
--------------------------------------------------------------------------------
C T I
GsCtiDll(): -1
GsCtiHandle(): -1
MainTapiMsgActiv(): N
MainCtiVorwahl(): 0
MainCtiDllPath(): C:\GS\
MainCtiServerIP(): 172.30.10.104
GsCtiUser(): hff\roland
cPass: *
AL_SY->WINCTIMODE: N
AL_SY->WINADDCTI: N
--------------------------------------------------------------------------------
L P T
GsLptCopiesVar(): 0
GsLptPrinterVar(): 
GsLptAutoPrintVar(): N
GsLptOutToFileVar(): N
GsLptDelPclVar(): J
GsLptOutPathVar(): 
GsLptOutPSubVar(): 
GsLptOutFileNameVar(): 
GsLptLastOutFileNameVar(): 
GsLptLastOutFileNSubVar(): 
--------------------------------------------------------------------------------
G U I
GsGuiBaseVar()[1] GsGuiY25ToGUIFaktor(): 27
GsGuiBaseVar()[2] GsGuiX80ToGUIFaktor(): 12
GsGuiBaseVar()[3] Font Groesse: 12
GsGuiBaseVar()[4] Font Name: Tahoma
GsGuiBaseVar()[5] Rahmendicke CRT: 5
GsGuiBaseVar()[6] FontComp.Name: 12.Tahoma
GsGuiBaseVar()[7] Rahmendicke GUI: 4
GsGuiBaseVar()[8] FontComp.Name Buttons: 11.Tahoma
GsGuiBaseVar()[9] TaskBar Hoehe: 40
GsGuiBaseVar()[10] FontComp.Name SLE: 12.Tahoma
GsGuiBaseVar()[11] Menuezeile Hoehe: 19
GsGuiBaseVar()[12] Titelzeile Hoehe CRT: 25
GsGuiBaseVar()[13] Titelzeile Hoehe GUI: 20
GsGuiBaseVar()[14] Buttons Hoehe: 19
GsGuiBaseVar()[15] Font Name nicht-prop.: Consolas
GsGuiBaseVar()[16] FontComp.Name nicht-prop.: 12.Consolas
GsGuiBaseVar()[17] FontComp.Name SLE n-prop: 11.Consolas
GsGuiBaseVar()[18] Input Border: .T.
GsGuiBaseVar()[19] FontComp.Name MLE: 16.Tahoma
GsGuiBaseVar()[20] FontComp.Name MLE n-prop: 16.Consolas
GsGuiBaseVar()[21] Font Groesse MLE: 16
AppDeskTop():CurrentSize(): {1600, 1200}
GsWinAppDeskTopCurrentSizeDual(): {3200, 1200}
GsGuiToCrtSize( AppDeskTop():CurrentSize() ): {134, 45}
dnGsDefPixels: 96
GsWinGetDesktopPixels(): {96, 96, .T.}
GsWinGetDesktopScale(): 1
MainFontGui(,,,1,.T.): {"9", "Tahoma", "Consolas"}
MainFontGui(,,,2,.T.): {"12", "Tahoma", "Consolas"}
MainFontGui(,,,3,.T.): {"17", "Tahoma", "Consolas"}
MainFontGui(,,,1,.F.): {"9", "Tahoma", "Consolas"}
MainFontGui(,,,2,.F.): {"13", "Tahoma", "Consolas"}
MainFontGui(,,,3,.F.): {"19", "Tahoma", "Consolas"}
Len( MEMVAR->R ): 17
--------------------------------------------------------------------------------
G s S y s D b T e m p V A R
--------------------------------------------------------------------------------
W O R K S P A C E - L I S T
lfd#: Alias     DBENAM   ges.Recs    akt.Rec Index akt SH RO DB-FileName
0001: AL_SY     DBFNTX          1          1     -   - SH    C:\TEMP\GS\3275250101.DBF
0002: AL_USR    ADSDBE          2          2     1   1 SH    \\172.29.59.5\VERWALTUNG\HFP1\P1USR001.DBF
0003: AL_MAIN   ADSDBE          1          1     -   - SH    \\172.29.59.5\VERWALTUNG\HFP1\P1\P1MAIN01.DBF
0004: AL_WU     ADSDBE         29          2     2   1 SH    \\172.29.59.5\VERWALTUNG\HFP1\P1\GSWU0001.DBF
0005: AL_SX1    ADSDBE        103        104     5   1 SH    \\172.29.59.5\VERWALTUNG\HFP1\P1\P1SX1001.DBF
0006: AL_LX1    ADSDBE         45         27     5   1 SH    \\172.29.59.5\VERWALTUNG\HFP1\P1\P1LX1001.DBF
0007: AL_HX1    ADSDBE        145        139     3   1 SH    \\172.29.59.5\VERWALTUNG\HFP1\P1\P1HX1001.DBF
0008: AL_PROJ   DBFNTX          1          1     -   - SH    \\172.29.59.5\VERWALTUNG\HFP1\K1CRAWLER\P1\K1PROJ01.DBF
0009: AL_UALL   DBFNTX         96         96     1   1 SH    \\172.29.59.5\VERWALTUNG\HFP1\K1CRAWLER\P1\K1UALL01.DBF
0010: AL_UONE   DBFNTX          1          1     1   1 SH    \\172.29.59.5\VERWALTUNG\HFP1\K1CRAWLER\P1\K1UONE01.DBF
0011: AL_STWA   DBFNTX      21002      18540     2   1 SH    \\172.29.59.5\VERWALTUNG\HFP1\K1CRAWLER\P1\K1STWA01.DBF
0012: AL_STWB   DBFNTX       7300       7076     1   1 SH    \\172.29.59.5\VERWALTUNG\HFP1\K1CRAWLER\P1\K1STWB01.DBF
0013: AL_LINK   DBFNTX         96         42     2   1 SH    \\172.29.59.5\VERWALTUNG\HFP1\K1CRAWLER\P1\K1LINK01.DBF
0014: AL_TONE2  DBFNTX          0          1     1   1       c:\temp\GS\3275431501.DBF
0015: AL_STWA21 DBFNTX       7302       4611     2   2 SH    C:\TEMP\GS\3275431701.DBF
--------------------------------------------------------------------------------
I N D E X K E Y - L I S T
ges.# Alias     Idx IndexKey
0001: AL_USR      1 Upper( USR )
0002: AL_WU       1 (Str(W_INDEX,2,0))
0003:             2 (PadR(Upper(W_KZ),3))
0004: AL_SX1      1 RecNo()
0005:             2 Upper(CSX1TX1)
0006:             3 Str(TIT_NR,10,0)
0007:             4 Str(KAP_NR,10,0) + Str(TIT_NR,10,0)
0008:             5 Str(KAP_NR,10,0) + CSX1IND1
0009: AL_LX1      1 RecNo()
0010:             2 Upper(CLX1TX1)
0011:             3 Str(LIT_NR,10,0)
0012:             4 Str(KAP_NR,10,0) + Str(TIT_NR,10,0) + Str(LIT_NR,10,0)
0013:             5 Str(KAP_NR,10,0) + Str(TIT_NR,10,0) + CLX1IND1
0014: AL_HX1      1 CHX1IND1
0015:             2 Upper(CHX1TX1)
0016:             3 Str(KAP_NR,10,0)
0017: AL_UALL     1 ( Str( LNR , 10 , 0 ) )
0018: AL_UONE     1 ( Str( LNR , 10 , 0 ) )
0019: AL_STWA     1 ( Upper( STICHWORT ) + Str( LNR , 10 , 0 ) )
0020:             2 ( Str( LNR , 10 , 0 ) + Upper( STICHWORT ) )
0021: AL_STWB     1 ( Upper( STICHWOEM ) )
0022: AL_LINK     1 ( Upper( LINK ) )
0023:             2 ( Str( LNR , 10 , 0 ) )
0024: AL_TONE2    1 ( Str( RNRUONE , 10 , 0 ) )
0025: AL_STWA21   1 ( Str( GEWICHTUNG , 10 , 0 ) + Upper( STICHWORT ) )
0026:             2 ( Str( GEWICHTUNG , 10 , 0 ) + Upper( STICHWORT ) )
--------------------------------------------------------------------------------
I N D E X F I L E - L I S T
ges.# Alias     Idx Index-FileName
0001: AL_USR      1 \\172.29.59.5\VERWALTUNG\HFP1\P1USR001.NTX
0002: AL_WU       1 \\172.29.59.5\VERWALTUNG\HFP1\P1\GSWU0001.NTX
0003:             2 \\172.29.59.5\VERWALTUNG\HFP1\P1\GSWU0002.NTX
0004: AL_SX1      1 \\172.29.59.5\VERWALTUNG\HFP1\P1\P1SX1001.NTX
0005:             2 \\172.29.59.5\VERWALTUNG\HFP1\P1\P1SX1002.NTX
0006:             3 \\172.29.59.5\VERWALTUNG\HFP1\P1\P1SX1003.NTX
0007:             4 \\172.29.59.5\VERWALTUNG\HFP1\P1\P1SX1004.NTX
0008:             5 \\172.29.59.5\VERWALTUNG\HFP1\P1\P1SX1005.NTX
0009: AL_LX1      1 \\172.29.59.5\VERWALTUNG\HFP1\P1\P1LX1001.NTX
0010:             2 \\172.29.59.5\VERWALTUNG\HFP1\P1\P1LX1002.NTX
0011:             3 \\172.29.59.5\VERWALTUNG\HFP1\P1\P1LX1003.NTX
0012:             4 \\172.29.59.5\VERWALTUNG\HFP1\P1\P1LX1004.NTX
0013:             5 \\172.29.59.5\VERWALTUNG\HFP1\P1\P1LX1005.NTX
0014: AL_HX1      1 \\172.29.59.5\VERWALTUNG\HFP1\P1\P1HX1001.NTX
0015:             2 \\172.29.59.5\VERWALTUNG\HFP1\P1\P1HX1002.NTX
0016:             3 \\172.29.59.5\VERWALTUNG\HFP1\P1\P1HX1003.NTX
0017: AL_UALL     1 \\172.29.59.5\VERWALTUNG\HFP1\K1CRAWLER\P1\K1UALL01.NTX
0018: AL_UONE     1 \\172.29.59.5\VERWALTUNG\HFP1\K1CRAWLER\P1\K1UONE01.NTX
0019: AL_STWA     1 \\172.29.59.5\VERWALTUNG\HFP1\K1CRAWLER\P1\K1STWA01.NTX
0020:             2 \\172.29.59.5\VERWALTUNG\HFP1\K1CRAWLER\P1\K1STWA02.NTX
0021: AL_STWB     1 \\172.29.59.5\VERWALTUNG\HFP1\K1CRAWLER\P1\K1STWB01.NTX
0022: AL_LINK     1 \\172.29.59.5\VERWALTUNG\HFP1\K1CRAWLER\P1\K1LINK01.NTX
0023:             2 \\172.29.59.5\VERWALTUNG\HFP1\K1CRAWLER\P1\K1LINK02.NTX
0024: AL_TONE2    1 c:\temp\GS\3275431501.NTX
0025: AL_STWA21   1 C:\TEMP\GS\3275431701.NTX
0026:             2 C:\TEMP\GS\3275431702.NTX
--------------------------------------------------------------------------------
Q R E M
--------------------------------------------------------------------------------
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ErrorSys.Prg erweitern

Beitrag von brandelh »

Ich würde die DLL nicht ändern sondern die PRG in jedes wichtige Projekt einbinden, so mache ich es.

1. Falls du so einen Fehler in deiner Fehlerbehandlung gemacht hast, brauchst du nur die PRG / OBJ auskommentieren, neu komplieren und du bekommst die original Meldung.
2. Nicht jedes Programm hat gleiche Variablennamen / Feldnamen, eine Fehlerbehandlung die für alle passt kann sehr komplex werden ;-)
Gruß
Hubert
Daniel

Re: ErrorSys.Prg erweitern

Beitrag von Daniel »

Vielleicht bin ich zu ungeduldig, aber ich möchte nochmals meine Frage von gestern stellen:
Daniel hat geschrieben:Zum Funktionieren der Errorsys in der STATIC FUNC StandardEH( oError):
- Was ist der Befehl, den letzten Befehl im Programm, der den Error auslöste, zu wiederholen (RETRY in AlertBox)?
- Welcher Befehl (falls nötig) führt die ErrorSys weiter zu der bekannten ALERTBOX, wo der Anwender wählen kann?
- was bewirkt RETURN(.T.) , was macht RETURN(.F.)

Ich habe die Doku abgesucht, aber keine Angaben dazu gefunden.
Die ErrorSys baue auch ich in das jeweilige Projekt ein. Wenn ich etwas erweitere, mache ich das erst mal nur in einem Programm, bis es sich bewährt hat.
Daniel

Re: ErrorSys.Prg erweitern

Beitrag von Daniel »

Also hier meine Erfahrungen mit der ErrorSys:

Wegen Abstürzen bei OrdListAdd() infolge Blockierung durch Kaspersky Antivirus (siehe Thread "Error OrdListAdd"), habe in die STATIC FUNC StandardEH( oError) - folgendes eingebaut:

Code: Alles auswählen

   ...
  STATIC nFehler_Stack :=0              // aus Bsp. v. HB
  STATIC nIndexOpen :=0                 // eingefügt  DN  2014
   ...
   DO CASE 
   ...
   CASE oError:operation == "OrdListAdd" .AND. oError:canRetry
      if nIndexOpen <= 5       
             nIndexOpen++   
             Sleep( 100)
             RETURN(.T.)                   // neuer Versuch (RETRY) 
      else
             nIndexOpen :=0
             * Break( oError )                  // bricht EXE sofort ab! EHS_CANCEL (?)
             * ErrorLog( oError, 2 )          // schreibt ErrorLog direkt 
             *QUIT                                  // -> besser nichts -> weiter im Ablauf
      endif
    ...
- RETURN(.F.) - kann im Fehlerfall zu FATAL-Error führen (entspricht wohl IGNORE ?)
-----------------------
Edit: Fehler und falsche Anmerkung korrigiert
Zuletzt geändert von Daniel am Sa, 13. Dez 2014 21:34, insgesamt 1-mal geändert.
DelUser01

Re: ErrorSys.Prg erweitern

Beitrag von DelUser01 »

Muss meinen Beitrag von weiter oben korrigieren:
Verwende nicht die errorsys.prg sondern einfach eigene Funktionen und binde diese über MainAppSys() per ErrorBlock() ein.
Daniel

Re: ErrorSys.Prg erweitern

Beitrag von Daniel »

Habe das ErrorSys wie oben erwähnt erweitert (Beitrag v. 11 Nov.).
Doch jetzt habe ich ein seltsames Errorlog vom Kunden erhalten, das mir kaum Hinweise auf den verursachenden Fehler gibt.
Ich tippe nicht das Ganze vom Papier ab, aber möglichst das Nötige:

Code: Alles auswählen

XBase Ver. 1.90.331     Windows XP
oError: args  :  -> VALTYPE C VALUE: Fehler BASE/5; Beschreibung: Interne Datenstrukturen beschädigt; Operation: alert; Thread ID: 1
-> VALTYPE: A VALUE: {"Abbrechen", "Ende mit LOG-Datei"}
oError: canDefault: N
oError: canRetry  : N
oError: canSubstitute: J
oError: cargo      :  NIL
oError: description: Interne Datenstrukturen beschädigt 
oError: gencode   :  41
oError: operation : alert 
oError: subcode   : 5
oError: tries     : 0

CALLSTACK:
Aufgerufen von STANDARDEH(158)              // i := Alert( cMessage, aOptions )
Aufgerufen von (B)ERRORSYS(55)                // der ErrorBlock()
[i]... ( wiederholt sich 5 mal ) ...[/i]
Aufgerufen von MAIN(360)
Die Stelle in MAIN(360) ist am Ende der MENU-Iteration, wo einige Standardbefehle stehen:
(358) Close databases
(359) clear typeahead
(360) set printer off ; set printer to
(361) set device to screen

Ist jetzt da etwas mit der AlertBox falsch, oder was kann die Ursache des Fehlers sein?
Ist es ein Folgefehler, und wenn ja, wie komme ich an den ursprünglichen Fehler ran?
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2824
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: ErrorSys.Prg erweitern

Beitrag von georg »

Hallo, Daniel -


schau mal in die entsprechenden Anweisungen in der ErrorSys.prg rein. Scheinbar gibt's ein Problem bei der Fehlerbehandlung, durch das wiederum ErrorSys.prg aufgerufen wird. So sieht's für mich zumindest aus.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: ErrorSys.Prg erweitern

Beitrag von AUGE_OHR »

Daniel hat geschrieben:Habe das ErrorSys wie oben erwähnt erweitert (Beitrag v. 11 Nov.).
ein Workaround um das "Problem" zu umgehen ...
Daniel hat geschrieben:

Code: Alles auswählen

XBase Ver. 1.90.331     Windows XP
oError: args  :  -> VALTYPE C VALUE: Fehler BASE/5; Beschreibung: Interne Datenstrukturen beschädigt; Operation: alert; Thread ID: 1
-> VALTYPE: A VALUE: {"Abbrechen", "Ende mit LOG-Datei"}
...
[i]... ( wiederholt sich 5 mal ) ...[/i]
Aufgerufen von MAIN(360)
Die Stelle in MAIN(360) ist am Ende der MENU-Iteration, wo einige Standardbefehle stehen:
(358) Close databases
...
(360) set printer off ; set printer to
...
wenn es wirklich die Zeile 360 sein sollte würde ich zunächst das ";" entfernen und es in 2 Zeilen aufteilen.
nun deutet der "Fehler BASE/5" aber eher auf eine DBF Operation was in Zeile 358 das "CLOSE ALL" wäre ...

Frage : arbeitest du mit RELATION ?

statt "Close Database" kannst du auch deine eigene Function schreiben siehe c:\ALASKA\XPPW32\SOURCE\SYS\AppExit.prg ( wo allerdings die RELATION fehlen)
Daniel hat geschrieben:Ist jetzt da etwas mit der AlertBox falsch, oder was kann die Ursache des Fehlers sein?
siehst du in der original c:\ALASKA\XPPW32\SOURCE\SYS\ErrorSys.prg ein ALERT() ?
Daniel hat geschrieben:Ist es ein Folgefehler, und wenn ja, wie komme ich an den ursprünglichen Fehler ran?
der rekursive Fehler liegt IMHO im ALERT(), aber ich sehe ein Problem das du es "erst" in der "1st" Errorsys abfängst.
wenn du bei USE / CLOSE etc. ein Problem hast würde ich die entsprechenden Befehle in eine Function schreiben und das mit einer "2nd" Errorsys und BEGIN / SEQUENZ ausstatten ... und einem Logfile.
gruss by OHR
Jimmy
Antworten