Special case: wrong order of updates for fly-away - delphi

How can I track down the location of the "Special case: wrong order of updates for fly-away!" error?
This error message is defined in Datasnap.DSIntf as
const
...
ERRCODE_FLYAWAY_WRONGORDER = 13; { Special case: wrong order of updates for fly-away }
...
DBERR_FLYAWAY_WRONGORDER = ERRBASE_ALC + ERRCODE_FLYAWAY_WRONGORDER;
but nowhere else in the Delphi sources can I find references to substring FLYAWAY_WRONGORDER.*
My intention was to compile with debug dcu's, then put a breakpoint on the line where the exception is raised and check the call stack UP to find the cause.
I'm currently stepping DOWN into the code until the error occurs, but that is less efficient (complex app).
Placing a TApplicationEvents with a breakpoint in its OnException handler does not give me usable call stack information:
So, how can I (efficiently) track down the place where this error is generated?
Background on what is going on:
Form uses DevExpress TcxScheduler connected to TcxSchedulerStorage component in datamodule, connected to nested TClientDataSets
Code saves all changes to these datasets (ApplyUpdates)
In BeginUpdate/EndUpdate for these DevExpress components, I then insert, delete and update records in these datasets, move around while doing so, even change parent IDs in detail datasets so that they drop from the current detail dataset 'in view'.The error occurs when I Edit, then Post a record doing exactly that.
Delphi Tokyo 10.2.3, Win32 app
Any other info on that error message is welcome, I was not able to find anything.
I actually 'fixed' the error by calling ApplyUpdates for the master dataset in a few places, but since I'm not really sure about the cause I want to investigate this further. So my question is not How do I fix the error in my code, it is How do I find the error in my code?
* There is a CheckForFlyAway routine in TCustomADODataSet.InternalPost in Data.Win.ADODB but we don't use ADO, I cannot set breakpoints in those routines.

Related

Vaadin: after upgrading to v23.0.1 (from 22.0.2): Error with Binder opening a Form

After upgrading to Vaadin 23.0.x (from former 22.0.2) I now keep getting the following error when opening a certain dialog:
2022-08-01 18:56:25,977 ERROR [http-nio-8085-exec-5] net.mmo.utils.kism.ui.views.nodes.NodeView: java.lang.IllegalStateException: All bindings created with forField must be completed before calling readBean
at com.vaadin.flow.data.binder.Binder.checkBindingsCompleted(Binder.java:3070)
at com.vaadin.flow.data.binder.Binder.readBean(Binder.java:2110)
at net.mmo.utils.kism.ui.views.nodes.NodeForm.readBean(NodeForm.java:487)
at net.mmo.utils.kism.ui.views.nodes.NodeForm.setNode(NodeForm.java:211)
This dialog has worked perfectly fine since I wrote it (using version 18.0.x about 2 years ago) and up to v22.0.2. I can't make sense of that error message and I don't understand what the issue could be here. I verified that issue going back and forth and the difference is really only the Vaadin version upgrade. Before it, the dialog works just fine and after it I get the above Exception when opening it.
I also can't quite believe what I think the message is stating here: if it would indeed check that I define or complete any bindings AFTER calling Binder.readBean() - how could it know that already in that very moment, i.e. when the code calls readBean() - as indicated by the stacktrace?
If there would indeed be any bindings being defined afterwards, IMHO it could only find that out AFTER said readBean()-call, i.e. when any additional bindings were actually defined, couldn't it?
So, could someone please try to "translate" or explain that issue or the background behind it to me?
The error basically states the problem: in the process of binding a field to a property (or getter/setter in general), the finishing step of actually binding was not undertaken. So the process was started with .forField() but never finished by .bind().
Since the error message as of now only states the fact, but not the culprit, a developer would be in need of a debugger to inspect the private state of the Binder, where the map incompleteBindings holds the current state of the Binder. The content of this map may help to find the culprit, e.g. by only holding one entry and by inspecting the flow of the program so far, that would conclude, what binding attempt failed. Or e.g. via the included field types.
Other than plain "bugs" by the developer, there are some potential reasons, why this suddenly happens by like an update or what places to look for:
multiple (re-)binding was recently added (e.g. to first bind "automatically" and then hand-tune the result); this holds potential, that older versions of the code just kept the initial binding and ignored the dangling second process.
the binding process uses a builder pattern; builder must build up on the result of the previous steps. This means, that in imperative code, there is the chance, that this chained call miss reassigning the build step. E.g.
var b = binder.forField(field)
if (predicate)
b.asRequired() // XXX: should be `b = b.asRequired()`
b.bind(...)
(this may or may not be a source for this kind of problem, but it's good to point out here, since the binder builder implementation actually switche(s|d) the builder (in the past)

Startup error during main form creation

Delphi XE5/32, on Windows10/64, generating Win32 VCL executable.
I am getting intermittent Access Violation errors that are associated with form creation. This error has also been seen, rarely, by some end-users (I'm currently in small-scale trials, with a test group of about 20 users).
This has been going on for months and until recently my attempts to find the problem were frustrated by the fact that it was so hard to reproduce. However, I have now finally been able to establish an environment that reproduces the error quite reliably. Bizzarely, I have discovered it is triggered by certain emails being displayed in my GMail account, in Chrome browser. The emails that cause the problem are completely consistent - see the video in https://www.devexpress.com/Support/Center/Question/Details/T395896. (I initially posted this query to the DevExpress support forum because I suspected one of their components was the cause, however now I doubt this).
I have now disabled my splash screen temporarily, and changed my previous auto-create datamodules to be created in the main form's OnCreate. The DPR is now, very simply:
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.Title := 'Topshare V3';
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.
That is, nothing happens prior to the CreateForm for the program's main form.
When the error is happening, the program either hangs silently during Application.CreateForm(TMainForm, MainForm), and before the main form's OnCreate is invoked; or it terminates before OnCreate, and invokes the form's OnDestroy. So the problem is occurring during the parsing of the DFM.
If I step the program in debug mode within the IDE when the error is active, there are several AVs raised during Application.CreateForm(TMainForm, MainForm). These are only apparent from the IDE so are, presumably, within try..except blocks. If I click Break on the first of these, the Call Stack is usually something like:
System.SysGetMem(???)
:00405423 SysGetMem + $43
System.Classes.TReader.ReadComponent(nil)
System.Classes.TReader.ReadDataInner(???)
System.Classes.TReader.ReadData($7BCCD90)
System.Classes.TComponent.ReadState(???)
Vcl.Controls.TControl.ReadState($9C6F098)
Vcl.Controls.TWinControl.ReadState($9C6F098)
:00aa0bcd TcxCustomGrid.ReadState + $29
System.Classes.TReader.ReadDataInner(???)
System.Classes.TReader.ReadData($7BF4230)
System.Classes.TComponent.ReadState(???)
Vcl.Controls.TControl.ReadState($9C6F098)
Vcl.Controls.TWinControl.ReadState($9C6F098)
System.Classes.TReader.ReadComponent(nil)
System.Classes.TReader.ReadDataInner(???)
System.Classes.TReader.ReadData($7BF3F50)
System.Classes.TComponent.ReadState(???)
Vcl.Controls.TControl.ReadState($9C6F098)
Vcl.Controls.TWinControl.ReadState($9C6F098)
System.Classes.TReader.ReadComponent(nil)
System.Classes.TReader.ReadDataInner(???)
System.Classes.TReader.ReadData($9B9C7A0)
System.Classes.TComponent.ReadState(???)
Vcl.Controls.TControl.ReadState($9C6F098)
Vcl.Controls.TWinControl.ReadState($9C6F098)
Vcl.Forms.TCustomForm.ReadState($9C6F098)
System.Classes.TReader.ReadRootComponent($9B9C7A0)
System.Classes.TStream.ReadComponent($9B9C7A0)
System.Classes.InternalReadComponentRes(???,???,$9B9C7A0)
System.Classes.InitComponent(TMainForm)
System.Classes.InitInheritedComponent($9B9C7A0,TForm)
Vcl.Forms.TCustomForm.Create(???)
Vcl.Forms.TApplication.CreateForm(???,(no value))
TopshareV3.TopshareV3
The apparent involvement of SysGetMem lead me to this Question: Delphi XE5 Acces Violation on app start
Accordingly I have enabled both Range Checking and Overflow Checking, but this does not help.
There must be something wrong with the DFM.
One aspect is that the main form inherits from an ancestor form type. The ancestor form has no components, just some methods. The ancestor form's source code does not include the default global variable declaration. So, the main form's form declaration is:
TMainForm = class(TABase)
and the DFM contains:
inherited MainForm: TMainForm
The form contains several nested frames, and also uses several ActionManagers, ActionToolbars, an ActionMainMenubar, a PopupActionbar, and a dxSkinController.
Can anyone shed any further light on what to look for, or how to proceed further??
EDIT: The call stack shown above is After the first AV. But I have already done the tracing you suggest. I put a breakpoint in System.Classes at line #10169, in TReader.ReadComponent. I then add watches on "Parent.name" and "CompName". Then, starting again in the IDE, I see the various main form components being created.
Previously, when the datamodules were being created first, I would see a number of components created, but the AV would always happen after hitting the breakpoint with watches showing the first View of the first cxGrid (DevExpress). If I added an extra grid to the form (and on the first panel to be created), without any properties being set, then the new grid would appear to trigger the AV. In other words, it seemed like the cxGrid was the problem - hence my contact with DevExpress support.
But postponing the creation of the datamodules, and eliminating my splash screen, has changed things (although the AV is still occurring). Now, it progresses well beyond the first grid; and, although a cxGrid still seems to be involved, I'm not sure that's relevant now (I have a lot of grids on the main form).
EDIT: Running in the IDE, there are 3 AVs (if I click Continue after each) - then the program hangs before my code in OnCreate executes: the first is $C0000005 with message 'access violation at 0x0040541d: read of address 0x002d001c'; and, twice, $C0000005 with message 'access violation at 0x00a8107a: read of address 0x00000068'.
EDIT: My initial breakpoint at Classes # 10169 now executes a few dozen times as the form components from the DFM are processed. On the now-critical component (still a cxGrid view), execution steps from Classes #10169 (in Treader.ReadComponent), to CreateComponent #10114, to Result.create #10129. From here there is a loop (or recursion) that includes an assembler block beginning at System #16752, and empty Tobject.Create at #15511. A breakpoint at System #15511 executes 29 times. Then, the 30th time through, the AV occurs at System #16757, CALL DWORD PTR [EAX] + VMTOFFSET TObject.NewInstance
EDIT: When stepping through execution when there's no error condition, things seem essentially the same as when there is: that is, the same sequence of calls. The same sequence described in the para above seems to be followed - except for no AV on the 30th pass or subsequently.
I have narrowed the problem down to DevExpress's dxSpreadSheetCore unit. If I include that in any Uses clause, the error is displayed; if I omit it, no error. I have submitted the problem to DevExpress, although I was not able to simplify my application enough to also give them a useful demonstration of the error.
My assumption, based on comments here, is that something in the initialization section of dxSpreadSheetCore (or in its dependant units) is causing heap corruption.

How do I keep Delphi from automatically expanding folded code regions?

I widely use {$Regions} in my units, but sometimes the VCL editor takes annoying decisions to automatically expand all regions. Is there any way to tell the editor not
to expand regions that are collapsed unless I explicity do this by clicking on the + button?
Update from comments:
Unfolding occurs,
with nested procs/funcs. Introducing a new nested "procedure" header. As soon as you type the 'p' character, all other nested procs/funcs are unfolded. This occurss also if, for instance, by mistake, you delete the "end" of any nested proc/func (or anything of the kind).
with regions. If you start a comment with "{", the Region immediately below is unfolded. Starting a comment with "(*" provoques all Regions below to be unfolded and same applies to all procs/funcs under those Regions.
Unfortunately this is one of the problems of Delphi whis is present athleast since Delphi XE if not even from older versions and still hasn't been fixed.
The reason why code gets automaticaly unfolded is the fact that as soon as Error Insight system detects any syntax error in your unit it treats all the code below that poiunt as non-valid and thus expans all folded code below that point.
So far the only way that I know to avoid this is to disable the Error Insight. But that means you won't be warned about any potentional syntax errors untill you try to compile your program.
But I seriously hope Embarcadero will go and fix this soon as it makeswhole code folding system to be useless unles you have Error Insight disabled as you spend more time folding the autoexpanded code again that writing any new code.
EDIT: Steps to reproduce this (one way of reproducing it)
Create new application
Create two new even handlers for OnCreate and OnClose for your form or any two other methods.
procedure TForm1.FormCreate(Sender: TObject);
begin
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//
end;
In case if you created even handlers make sure there is athleast some code in the lowest handler metrhod or athleast one commented line so that optimizer doesent automatically remove the "empy" event handler.
Now in top event handler write "Form." and you will se how bottom event handler will be automatically expanded.
You will see that at this point delphi desent even know when or where current method code block in which syntax error has been detected ends. And this also makes it imposible to properly detect any code blocks below that point.

class EVariantTypeCastError with message 'Could not convert variant of type (String) into type (Double)

Using Delphi and FastReport I get this error message while debugging inside Delphi immediately after this line:
<FastReport_Component>.ShowReport(true);
Then this error appear:
Project myapp.exe raised exception class EVariantTypeCastError with message 'Could not convert variant of type
(String) into type (Double)'.
It appears twice before displaying the report. but if I run myapp without debugging no error message appear.
How I can find which memo cause this error ? the report has so many memos. some has also expressions inside using IIF and the error message does not display any more info.
This is just the debugger. It's probably just getting an expected error (one handled by a try..except in the FR code) and properly dealing with it, but the debugger has no way of knowing that and tells you the exception happened. (It's a common issue when working with Indy, which raises exceptions as part of normal program flow.)
There are three ways to deal with this situation when debugging:
Just hit Continue on the exception dialog when it appears. (You can tell it's a debugger exception because you get the Break or Continue option, and because it only happens when debugging.)
You can disable a specific exception class (or all exceptions) when debugging, using the Tools->Options->Debugger Options. In this case, you can add EVariantTypeCastError to the list of exceptions to ignore.
(My preferred method) Use the Advanced Breakpoint Properties dialog to skip the debugger's exception handling around the specific line of code you know will raise the exception you want to ignore.
Set a breakpoint on the line immediately before the problem code line.
Right-click the breakpoint on the line before, and choose Breakpoint Properties from the context menu.
Click the Advanced button on the Breakpoint Properties dialog, and in the Actions groupbox, uncheck Break and check Ignore subsequent exceptions.
Repeat the previous steps on the line after the problem code, except check Break and uncheck Ignore subsequent exceptions on this second breakpoint.
Run your code as usual. The debugger will skip it's exception handling on the code between the two breakpoints.
The advantage of option #3 is that it ignores all exception handling, but only on the code block between the two breakpoints, so you still get exceptions in all other areas of your code that may be valid exceptions in the debugger.
I got this exact same error but not with FastReport. I'll leave the context of my error, as it may help someone else. I got this error on:
RESTRequest.Execute();
I was using the TClientDataSet with TRESTResponseDataSetAdapter so that after a request to my web service the adapter would load a data set with the JSON string returned by the web service. This data set was being used to automatically check/uncheck checkboxes and load textedits and comboboxes. Since TJSONObject does not parse booleans correctly in json, I changed some checkboxes to check/uncheck based on an integer value instead of a boolean. I was then changing my webservice so that it looks for boolean columns in the datatable to an integer value 1 or 0. For some reason (my fault entirely), I was outputting a json with "" in that field instead of the integer ("1" or "0"). And this yielded that exact error. After correcting this, the error disappeared.
I had a similar issue in FastReport. In my case, it was a wrong Format applied to a MemoView. I could find the name of the offending component this way:
Use Break to stop the execution
In the Call Stack panel, find the latest call from a fastreport class (in my case: frxClass.TfrxCustomMemoView.FormatData(...) and double click it.
if you don't have the source code od Fast Report, a dialog appears - just hit Cancel
in Local Variables panel, you will probably see name of the offending component / value / format.

Lazarus Free Pascal / Delphi - RunError 211

I'm trying to connect my Windows XP program (Lazarus) to my Ubuntu postgres server.
When the Lazarus program runs, it seems to compile fine but I get this error:
Project ... raised exception class 'RunError(211)'.
Then it terminates execution (and I don't see any output), and opens up a file customform.inc. In that file, it shows a procedure procedure TCustomForm.DoCreate; where it highlights a line: if Assigned(FOnCreate) then FOnCreate(Self);
I believe this is one of the system's files.
I never get to see any output.
What could this be? Thanks!
MORE INFO:
I've narrowed down the error to this line:
dbQuery_Menu.SQL.Text:='Select * From "tblMenus"';
dbQuery_Menu.Open;
the exception is triggered when the OPEN statement gets executed.
BTW, dbQuery_Menu is defined as a TSQLQuery component.
Clueless! :(
Run error 211 appears when you try to call an abstract method. Check this link from more information on FreePascal/Lazarus runtime errors.
Since you say all is done by code and you have no visual components, the problem probably lies in your code trying to use an ancestor component which has not overriden the Open method. You should be able to solve this by using the correct descendant component.
Another possibility, although I would strongly recommend to avoid this one, is to override the Open method yourself. It should be avoided because if you are using an ancestor component then you probably would have to override more abstract methods.
HTH
After nearly 5 days I found the answer. Many thanks to all thos e ho have contributed with their ideas ESPECIALLY RRUZ, RBA and Guillem Vicens. there are other related posts all connected to getting the FIRST Lazarus program working with PostgreSQL.
Summary.
The biggest mistake I made here was that I used the TSQLConnection component. Don't do this. Instead use the TPQConnection.
Everything is done through code. We're not using any draggable components from the top tab.
Don't rely on the Lazarus docs (wiki) at least for working with PG DBs.. It is outdated. Some of the examples can be pretty misleading.
Make sure that fields have some default values. For example, if a Boolean field has no true or false (t/f) set, this may lead to errors.
And that's it! I hope many postgres+Lazarus newbies will find this useful.
From here - http://www.network-theory.co.uk/docs/postgresql9/vol2/SQLSTATEvsSQLCODE.html - -211 (ECPG_CONVERT_BOOL) This means the host variable is of type bool and the datum in the database is neither 't' nor 'f'. (SQLSTATE 42804)

Resources