Page 1 of 2
discover runtime error in the RDD classes when running as Windows Service
Posted: Fri Jun 17, 2022 3:50 am
by wriedmann
Hi Robert,
I have now searched a lot until I found my error: an invalid field specification in a DBServer.
My application is running as a Windows service and the runtime error is not showing up (of course!).
If I remember correctly, there is a possibility to make the runtime call an own error handler instead of the X# error dialog.
Unfortunately I cannot find that piece of documentation now.
Thank you very much for any help!
Wolfgang
discover runtime error in the RDD classes when running as Windows Service
Posted: Fri Jun 17, 2022 6:41 am
by robert
Wolfgang,
Have you tried registering your error handler with ErrorBlock() ?
Robert
discover runtime error in the RDD classes when running as Windows Service
Posted: Fri Jun 17, 2022 6:49 am
by Chris
Hi Wolfgang,
I think it's ErrorBlock() you are looking for?
Edit: Oops, I was too slow
.
discover runtime error in the RDD classes when running as Windows Service
Posted: Fri Jun 17, 2022 7:03 am
by wriedmann
Hi Robert, hi Chris,
thank you very much!
It was too simple - I was searching for some other call.
I will add that and let you know.
Again: thank you for your great support!
Wolfgang
discover runtime error in the RDD classes when running as Windows Service
Posted: Fri Jun 17, 2022 8:20 am
by wriedmann
Hi Robert, hi Chris,
when calling this function from a Core dialect application: how can I create the codeblock?
Wolfgang
discover runtime error in the RDD classes when running as Windows Service
Posted: Fri Jun 17, 2022 10:26 am
by Chris
Hi Wolfgang,
Unless Robert has a better idea, I think you'll need to create a small VO dialect library that does this job and it is called by your main core app.
.
discover runtime error in the RDD classes when running as Windows Service
Posted: Fri Jun 17, 2022 10:48 am
by robert
Wolfgang, Chris,
To create a codeblock at runtime you should have a look at the compile method of the Workarea class:
https://github.com/X-Sharp/XSharpPublic ... a.prg#L991
Robert
discover runtime error in the RDD classes when running as Windows Service
Posted: Fri Jun 17, 2022 11:16 am
by wriedmann
Hi Robert,
thank you very much! Indeed, that helps.
So I can pass my process class in the codeblock parameter, and call the correct method afterwards.
I'll show my code when it works.
Wolfgang
discover runtime error in the RDD classes when running as Windows Service
Posted: Sat Jun 18, 2022 4:45 pm
by wriedmann
Hi Robert (and all that may be interested),
this is my class to handle these errors:
Code: Select all
using System.Reflection
using XSharp.RDD.Enums
using XSharp.RDD.Support
using XSharp.RDD
public delegate XSErrorHandler( oError as XSharp.Error ) as void
class XSRuntimeHandler
static protect initonly _oHandler as XSRuntimeHandler
protect _oError as XSharp.Error
protect _oErrorHandler as XSErrorHandler
static constructor()
_oHandler := XSRuntimeHandler{}
return
protected constructor()
self:_SetErrorBlock()
return
protected method _SetErrorBlock() as void
local oBlock as ICodeblock
local oMC as IMacroCompiler
local oType as System.Type
local lIsBlock as logic
local lAddsMemvars as logic
local lIsCodeBlock as logic
local oBlockType as System.Type
local cBlock as string
local oCbType as System.Type
oBlock := null
cBlock := "{|o| XSRuntimeHandler.HandleError(o) }"
try
oMC := XSharp.RuntimeState.MacroCompiler
oType := typeof( Workarea )
if oMC != null
oBlock := oMC:Compile( cBlock, true, oType:Module, out lIsBlock, out lAddsMemvars )
lIsCodeBlock := false
oBlockType := oBlock:GetType()
while oBlockType != null
if oBlockType:FullName != "XSharp._Codeblock"
oBlockType := oBlockType:BaseType
else
lIsCodeBlock := true
exit
endif
enddo
if ! lIsCodeBlock
oCbType := null
foreach oAsm as Assembly in AppDomain.CurrentDomain:GetAssemblies()
if oAsm:GetName():Name:ToLower() == "xsharp.rt"
oCbType := oAsm:GetType( "XSharp._Codeblock" )
if oCbType == null
foreach oT as Type in oAsm:GetTypes()
if oT:FullName:ToLower() == "xsharp._codeblock"
oCbType := oT
exit
endif
next
endif
endif
if oCbType != null
exit
endif
next
if oCbType != null
oBlock := (ICodeblock) Activator.CreateInstance( oCbType, <object>{ oBlock, cBlock, lIsCodeBlock, lAddsMemvars} )
endif
endif
endif
ErrorBlock( ( codeblock ) oBlock )
catch oEx as Exception
HandleError( XSharp.Error{ oEx } )
end try
return
static property Error as XSharp.Error get _oHandler:_oError
static property ErrorHandler as XSErrorHandler set _oHandler:_oErrorHandler := value
static method HandleError( o as XSharp.Error ) as void
_oHandler:_oError := o
if _oHandler:_oErrorHandler != null
_oHandler:_oErrorHandler:Invoke( o )
endif
return
end class
and that is how it is used:
Code: Select all
using XSharp.RDD.Enums
using XSharp.RDD.Support
using XSharp.RDD
function Start( ) as void
local oRDETester as RDETester
System.Console.WriteLine("Start test...")
oRDETester := RDETester{}
if oRDETester:Initialize()
oRDETester:Process()
endif
oRDETester:Dispose()
System.Console.WriteLine("End test...")
System.Console.WriteLine("Press return...")
System.Console.ReadLine()
return
class RDETester implements IDisposable
protect _oServer as XSharp.VO.SDK.DbServer
protect _cFileName as string
constructor()
_cFileName := "c:tempRDETester.dbf"
return
method Initialize() as logic
local aStruct as array
XSRuntimeHandler.ErrorHandler := HandleError
if System.IO.File.Exists( _cFileName )
System.IO.File.Delete( _cFileName )
endif
aStruct := ArrayNew( 2 )
aStruct[1] := { "F1", "C", 20, 0 }
aStruct[2] := { "F2", "N", 10, 2 }
DbCreate( _cFileName, aStruct , "DBFCDX")
DbCloseArea()
_oServer := XSharp.VO.SDK.DbServer{ _cFileName, true, false, "DBFCDX" }
_oServer:Append( true )
return true
method HandleError( o as XSharp.Error ) as void
System.Console.WriteLine( "Error has occurred" )
System.Console.WriteLine( "Subsystem:" + o:SubSystem )
System.Console.WriteLine( "Function:" + o:FuncSym )
System.Console.WriteLine( "Description:" + o:Description )
return
method Process() as logic
_oServer:FieldPut( "F1", "hallo" )
_oServer:FieldPut( "F2", 100 )
_oServer:FieldPut( "F3", 100 )
return true
method Dispose() as void
if _oServer != null
if _oServer:Used
_oServer:Close()
endif
_oServer := null
endif
return
end class
The XIDE export file is here:
I'm more than sure that many of will find many things to make better.... but this is a proof of concept how things could work.
Wolfgang
discover runtime error in the RDD classes when running as Windows Service
Posted: Mon Jun 20, 2022 7:08 pm
by wriedmann
Hello,
as I expected, there is a lot of space for improvement.
The _SetErrorBlock method can be simplified:
Code: Select all
protected method _SetErrorBlock() as void
local oBlock as ICodeblock
oBlock := {|o| XSRuntimeHandler.HandleError( o ) }
ErrorBlock( ( codeblock ) oBlock )
return
The code I posted on saturday is only needed if you like to pass in your own errorhandler code.
Wolfgang