none
Mysterious side effect of try..catch RRS feed

  • Question

  • Hello all
     
    While working with Sap Business One Api provided in the form of
    COM objects, I found an instance where the presence of a
    try..catch block affected the execution of the code although no
    exceptions were raised. The call to doSomething() in this code:
     
    try
    { ret = Git_DIApi.sCmp.vCmp.Connect(); }
    catch
    {}
    doSomething();
     
    works differently the same call here:
     
    ret = Git_DIApi.sCmp.vCmp.Connect()
    doSomething();
     
    Both cases have been tested several times in exactly the same
    conditions, but I couldn't create a standalone project demon-
    strating it.
     
    As I understand, if a run of a fragment of code generates no ex-
    ceptions it must in no way depend on any try..catch blocks it
    may contain... Futhermore, surrounding the call to Connect()
    with try..finally{} doesn't have the affect that try..catch{}
    does. Could it have something to do with the way CLR interacts
    with COM? What are you suggestions?
     
    --
    Anton Shepelev (via NNTP Bridge)
     
    Wednesday, September 12, 2012 3:56 PM

All replies

  • "works differently the same call here:"

    Different in what way?

    Wednesday, September 12, 2012 4:04 PM
    Moderator
  • Mike Danes: "Different in what way?"
     
    Futher in the code I get a PickLists business object
    via:
     
    PickLists PL = (PickLists)Git_DIApi.sCmp.vCmp.GetBusinessObject(BoObjectTypes.oPickLists);
     
    fill it with appropriate data and add to the
    database by calling:
     
    PL.Add();
     
    If the connection was made inside a try..catch, this
    last call returns an SAP-specific error: "-2028: No
    matching records found," but if it was done without
    the try..catch the object is addeed successfully.
    This is a subtle and strange effect, not like an
    object not working or not being available at all...
    It's only that certain objects (PickLists) generated
    by it work incorrectly.
     
    Futhermore, if to leave the contents of the PickList
    empty and fill only the mandatory fields, both
    versions work correctly adding an empty document to
    the system.
     
    --
    Anton Shepelev (via NNTP Bridge)
     
    Wednesday, September 12, 2012 4:16 PM
  • Hi Anton,

    How do you implement the add method? It is more related to your code. Please share more.

    Have a nice day.


    Ghost,
    Call me ghost for short, Thanks
    To get the better answer, it should be a better question.

    Thursday, September 13, 2012 9:44 AM
  • CrazyGhost_Von,
     
    It is really a disappointing and intermittend error,
    and today it seems to have another cause, which is
    connected with optimization. Inside a catch block
    we had:
     
    int ret = Git_DIApi.sCmp.vCmp.SetSboLoginContext(Git_DIApi.sCmp.UIConnStr);
    if (ret != 0)
    { // This is called by optimization algorithm even if ret is 0.
    errTxt = Git_DIApi.sCmp.vCmp.GetLastErrorDescription();
    ...
    }
     
    The block for (ret != 0) should never have been
    called, because the ret was 0 on all tests, but due
    to optimization errMsg was calculated beforehand
    thereby producing said side effect. How can I
    disable this kind of optimization? Unchecking the
    "Optimize code" setting in Visual Studio didn't
    help... I'll write about this to SAP.
     
    --
    Anton Shepelev (via NNTP Bridge)
     
    Thursday, September 13, 2012 11:22 AM
  • "The block for (ret != 0) should never have been called, because the ret was 0 on all tests, but due to optimization errMsg was calculated beforehand thereby producing said side effect"

    That sounds like a JIT compiler bug.

    "Unchecking the "Optimize code" setting in Visual Studio didn't help"

    Try to disabled optimizations on that method with this attribute:

    [MethodImplAttribute(MethodImplOptions.NoOptimization)]

    Thursday, September 13, 2012 11:48 AM
    Moderator
  • Mike Danes: "Try to disabled optimizations on that
    method with this attribute:
     
    [MethodImplAttribute(MethodImplOptions.NoOptimization)]"
     
    No effect. And I again can't isolate it into a
    separate minimal working example...
     
    --
    Anton Shepelev (via NNTP Bridge)
     
    Thursday, September 13, 2012 11:58 AM
  • But how do you know that

    "The block for (ret != 0) should never have been called, because the ret was 0 on all tests, but due to optimization errMsg was calculated beforehand"

    Did it look as if it happened that way or have you looked at assembly code and saw that the code is doing this?

    Thursday, September 13, 2012 12:15 PM
    Moderator
  • Mike Danes:
    "Did it look as if it happened that way or have you
    looked at assembly code and saw that the code is
    doing this?"
     
    It looks that way, because an unconditional call to
     
    Git_DIApi.sCmp.vCmp.GetLastErrorDescription()
     
    causes the same error as its being placed inside the
    never-called if-block. I don't understand .NET
    assembly.
     
    --
    Anton Shepelev (via NNTP Bridge)
     
    Thursday, September 13, 2012 12:56 PM
  • If it never be called, it must be interrupted by exceptions or errors.

    Ghost,
    Call me ghost for short, Thanks
    To get the better answer, it should be a better question.

    Friday, September 14, 2012 9:11 AM
  • Ghost:
    "If it never be called, it must be interrupted by
    exceptions or errors."
     
    It is never called because the condition (ret != 0)
    is always false.
     
    "To get the better answer, it should be a better
    question."
     
    Fair enough. I can demostrate it over Remote
    Resktop, if the management allows. I'll ask them.
    Anyway, the SAP support will likely ask me to do the
    same soon.
     
    --
    Anton Shepelev (via NNTP Bridge)
     
    Friday, September 14, 2012 10:58 AM
  • Hi Anton,

    Where is the code "(ret != 0)", it seems you didn't tell us all.

    Have a nice day.


    Ghost,
    Call me ghost for short, Thanks
    To get the better answer, it should be a better question.

    Monday, September 17, 2012 2:43 AM
  • Ghost:
     
    > Where is the code "(ret != 0)", it seems you
    > didn't tell us all.
     
    I mentioned it in my third post to the thread.
    Here's the full version:
     
    int ret = Git_DIApi.sCmp.vCmp.SetSboLoginContext(Git_DIApi.sCmp.UIConnStr);
    if (ret != 0)
    { // when below line is commented, code returns "Success",
    // otherwise it returns "Error...":
    errMsg = Git_DIApi.sCmp.vCmp.GetLastErrorDescription();
    }
    else
    { ret = Git_DIApi.sCmp.vCmp.Connect(); }
    if (ret == 0)
    { Git_DIApi.sCmp.DBName = Git_DIApi.sCmp.vCmp.CompanyDB;
    if (!Test(Git_DIApi.sCmp.vCmp, 1096, 0, ref errMsg))
    { Console.WriteLine("Error: " + errMsg); }
    else
    { Console.WriteLine("Success"); }
    }
     
    I can demostrate it via GoToMeeting.
     
    --
    Anton Shepelev (via NNTP Bridge)
     
    Monday, September 17, 2012 8:10 AM
  • Hi Anton,

    Thank you for your clarification.

    I think I am lost in this issue. Sorry.

    Have a nice day.


    Ghost,
    Call me ghost for short, Thanks
    To get the better answer, it should be a better question.

    Monday, September 17, 2012 9:08 AM