Hi everyone
I think the title already nails the problem pretty accurately!
I have got the following code within the OnAfterProcessChange event handler of a TDABusinessProcessor:
// check whether the stored procedure returns a json structure containing all ambiguous accounting fields
// if so, this means that the user has to specifiy which ones shall be applied
if ParamByName(par_AmbiguousAccountingFields).AsString <> '' then
begin
try
// convert the json array into a delphi structure
AmbiguousAccountingFields := TAmbiguousAccountingFields.Create;
JSonValue := TJSonObject.ParseJSONValue(ParamByName(par_AmbiguousAccountingFields).AsString);
for Item in JSonValue as TJSONArray do
begin
with AmbiguousAccountingFields.Add do
begin
ItemTypeCode := Item.GetValue<string>('ItemTypeCode');
ItemTypeName := Item.GetValue<string>('ItemTypeName');
ValueOnCurrentSemester := Item.GetValue<Currency>('ValueOnCurrentSemester');
ValueOnPreviousSemesterParticipant := Item.GetValue<Currency>('ValueOnPreviousSemesterParticipant');
end;
end;
// finally raise an exception containing all ambiguous accounting fields
raise EAmbiguousAccountingFields.Create('', AmbiguousAccountingFields);
finally
JSonValue.Free;
end;
end;
The problem is that on the client I only ever receive a EDAApplyUpdateFailed having no inner exception whatsoever!
Can you help me raising an exception on the client actually containing the necessary payload?`
Hi,
looks like you have set BP.RaiseExceptionAtError to true (for personal BP) or DataService.ReturnUpdateFailureDelta to false (for autogenerated BP)
so EDAApplyUpdateFailed exception is raised.
by other hand, you can try get your original error message from the EDAApplyUpdateFailed.Message property:
constructor EDAApplyUpdateFailed.Create(aChange: TDADeltaChange; anOriginalException: Exception);
begin
if (anOriginalException<>NIL) then begin
inherited Create(anOriginalException.Message); //<<<<
end
else inherited Create('');
Unfortunately the RaiseExceptionAtError Flag on the personal BP ist already set to false and yet, an EDAApplyUpdateFailed Exception is all I get on the client :-/
I am afraid you didn’t understand the problem I am facing. I do NOT want to provide the client with a simple message but with a RemObjects Datastructure which the client can then further process. When you take a closer look at the code snippet within my initial post, you will realize that the EAmbiguousAccountingFields Exception takes an object of type TAmbiguousAccountingFields, which is itself a list of TAmbiguousAccountingField objects. I need this structure on the client and not a simple message. I am posting the client side code snippet as well in order to illustrate the basic idea:
try
// store this course participant
DataSet.ApplyAndUpdate(False);
except
// THIS IS ALWAYS AN EDAApplayUpdateFailed
on Exp: Exception do
begin
// THIS IS ALWAYS NIL (WHERE IS MY EXCEPTION????)
if Exp.InnerException is EAmbiguousAccountingFields then
begin
FormAccountingSelector := TFormAccountingSelector.Create(Self);
FormAccountingSelector.AmbiguousAccountingFields := (Exp.InnerException as EAmbiguousAccountingFields).AmbiguousAccountingFields;
try
if FormAccountingSelector.ShowModal = mrOk then
begin
FDMDisposal.tbl_CourseParticipantDetail.FieldByName('AccountingSource').AsString := FormAccountingSelector.SelectedAccountingSource;
DataSet.ApplyAndUpdate(False);
end;
finally
FormAccountingSelector.Free;
end;
end;
end;
else
raise;
end;
I don’t want to be rude or anything but did you actually read my message?
EDAApplyUpdateFailed.Message is of type string and I spent a considerable amount of time stating excplicitly that simply returning a string is useless as the payload of this exception is not ment for the end customer to read but rather for the client to interpret and take actions based on the information provided by that very payload! The payload of the exception I am raising on the server is a TAmbiguousAccountingFields object and not a &%*ç string!
As I already said, RemObjects/Data Abstract don’t use/support InnerException property.
this means that Exp.InnerExceptionwill be alwaysnil.
at this moment, you can only get OriginalException.Message value in EDAApplyUpdateFailed.Message because only this value is passed from server inside EDAApplyUpdateFailed.
if you declare your exception (i.e. EAmbiguousAccountingFields ) in RODL (I suppose you are using RODL-based server), you can pass it from server-side to client-side.
So what you’re basically saying is that when using dataabstract its not possible to provide the requesting client with anything different than a simple string as means of a feedback to a failed client request?
by default - DA passes only original message inside EDAApplyUpdateFailed.Message.
if you declare new exception in RODL, you can pass almost everything - arrays, complex types (aka structs), streams, simple types inside your exception.
Well, this is exactly what I am doing. I did define a new custom exception type in the RODL named EAmbiguousAccountingFields and I am raising that very exception in the… …you know… …please read my initial question… …or the title of this thread which states that I am exactly doing what you are supposing - it just doesnt work!