#1 Re: mORMot 2 » ObjectToJSON / TTextWriter » 2023-07-24 22:42:45

Thank for recommendation!
Though I think it would require a lot of custom serializers.

Here is more information with examples: I had this following function which I called for any object class:

function TWIERestExecute.ObjectToJSON(Value: TObject; Options: TTextWriterWriteObjectOptions = [woDontStoreDefault]): RawUTF8;
var
  temp: TTextWriterStackBuffer;
  aTextWriter: SynCommons.TTextWriter;
begin
  if Value = nil then
    result := NULL_STR_VAR
  else
  begin
    aTextWriter := DefaultTextWriterSerializer.CreateOwnedStream(temp);
    try
      aTextWriter.OnWriteObject := OnWriteObject;
      aTextWriter.CustomOptions := aTextWriter.CustomOptions + [twoForceJSONStandard];
      aTextWriter.WriteObject(Value, Options);
      aTextWriter.SetText(result);
    finally
      aTextWriter.Free;
    end;
  end;
end;

And the OnWriteObject implement was as such:

function TWIERestExecute.OnWriteObject(Sender: SynCommons.TTextWriter; Value: TObject; PropInfo: pointer; Options: TTextWriterWriteObjectOptions): boolean;
begin
  if ((FBasePropInfosToInclude.IndexOf(PropInfo) <> -1) or (FPropInfosToInclude.Count = 0) or (FPropInfosToInclude.IndexOf(PropInfo) <> -1)) and
     (FBasePropInfosToExclude.IndexOf(PropInfo) = -1) then
    result := False
  else
    result := True; {Will skip this property}
end;

The above class fields are just TLists, which I used as such:

  FBasePropInfosToExclude := TList.Create;
  FBasePropInfosToExclude.Add(GetPropInfo(TypeInfo(TWebOutputRemotable), 'ErrorCode'));
  FBasePropInfosToExclude.Add(GetPropInfo(TypeInfo(TWebOutputRemotable), 'ErrorMessage'));

The client code could then define what properties it wanted to serialize, without needing a custom serializer for each class I use.
If I understand the example you sent I would need to define a custom serializer for each class that is getting serialized right?

Edit: The TLists are actually getting populated using strings received through a rest API, in the format classname.propertyname, and so it varies from call to call.
My example does not reflect that.

#2 mORMot 2 » ObjectToJSON / TTextWriter » 2023-07-24 20:46:48

AntoineGS
Replies: 3

In mORMot1 I was using similar code to ObjectToJSON to serialize objects with runtime filtering on what fields should end up in the JSON.
I was doing it by using TTextWriter.OnWriteObject (the rest of the code was identical to the ObjectToJSON procedure), and returning True on any field/object that should not be serialized.
Is there a way of achieving this using mORMot2? I have failed to find a way to do so sad .

#3 mORMot 1 » TSynLog Exception Trapping and BPLs » 2023-06-09 20:27:17

AntoineGS
Replies: 0

I have been using TSynLog with the following Levels:
  TSynLog.Family.Level := [sllException,sllExceptionOS];
in a lot of different applications and it has saved me countless hours of debugging when hunting for hard to reproduce errors (so thank you!).

I am now running into an issue in a very large application where most of the code is loaded dynamically through BPLs.
I have narrowed it down to the Exception logger ending up in SynLog.GetInstanceMapFile, which then creates a new TSynMapFile without any parameters.
Therefore in the constructor it will locate the map file (fMapFile) by calling GetModuleName(hInstance).
Since this is always done in the context of the logger and from what I could find online, hInstance refers to the bpl that contains the logger and not the code where the Exception occurred.
Therefore it is never able to find the right map file unless it happens to be an exception located in the same package as the logger (which in my case is never).

Here is the full stack that gets me to TSynMapFile.Create:
Exception -> SynLog.SynRtlUnwind -> SynLog.LogExcept -> SynLog.SynLogException -> SynLog.TSynMapFile.Log -> SynLog.GetInstanceMapFile -> SynLog.TSynMapFile.Create

As a quick hack I changed GetModuleName(hInstance) to GetModuleName(GetModuleHandle(nil)) ensuring it will get the hInstance of the main exe, but that is obviously not a great solution.
Would you have any ideas as to how to tackle this?

Thank you!

#4 Re: mORMot 1 » Exception in IDE Only » 2020-06-16 13:57:47

I just did a pull and re-ran the tests and everything ran great, thank you!

#5 Re: mORMot 1 » Exception in IDE Only » 2020-06-15 20:27:05

Alright so the issue started creeping up when running the applications in Release as well, and was more common when the CPU was under load so I took some time to locate the issue.
It would seem the TWebSocketProcessClient is not ready when the first call is done.
I was able to get it working by doing the following but I do not feel like it is a good solution, we could end up in an infinite loop as there might be scenarios where it will stay at wpsCreate:

constructor TWebSocketProcessClient.Create[...]
  [...]
  while fState = wpsCreate do
    sleep(0);
end;

Would there be a better solution for this?

#6 Re: mORMot 1 » Exception in IDE Only » 2020-04-02 13:10:55

Sorry about that, I moved it to pastebin.

Would you have any idea on how I can mitigate the issue?
Without the IDE I won't be able to debug client-side issues so that would make things pretty complicated.

#7 mORMot 1 » Exception in IDE Only » 2020-04-01 21:34:21

AntoineGS
Replies: 6

Hi,

I am using the framework for its WebSocket capabilities, and I am running into an exception when running it through IDE only (F9), when running outside of it (CTRL-F9) everything is good.
The Exception:

 First chance exception at $77134192. Exception class EServiceException with message 'TServiceFactoryClient.Create(): IWSSGeneral interface or TSQLRestRoutingREST routing not supported by server [URI root/WSSGeneral._contract_ [] returned status 'Service Unavailable' (503 - Check the communication parameters and network config)]'. Process BugReportClient.exe (12248)

I am using Delphi 2010, and have confirmed the issue on two different environments (same version of Delphi).
On one environment it fails about half of the time, while on the other it is 100% of the time.
I did a pull on Monday (3/30/2020) so my sources are pretty recent.

I created a project with both server and client which reproduces the issue, the loop is in case whoever runs it is on a machine that works most of the time.

Unfortunately I am not able to figure out the source of the issue on my own (except the line which raises the error but as to why it does), any help would be greatly appreciated!

Client:
https://pastebin.com/wjZ10jE1

Server:
https://pastebin.com/0nyktRsW

Thank you!

Board footer

Powered by FluxBB