DatasetModel:SaveChanges Trapping Errors
 
Forums / SmartComponent Library - Developer Forum / DatasetModel:SaveChanges Trapping Errors

DatasetModel:SaveChanges Trapping Errors

20 posts, 0 answered
  1. Roger Blanchard
    Roger Blanchard avatar
    381 posts
    Registered:
    29 Jun 2018
    12 Feb 2020
    Link to this post
    We use the code below to save a record in the DB and return to the caller if it was successful. We just received a report that periodically records are not being saved. In reviewing logs it appears that if PASOE is being shutdown our CATCH logic below will fail. Should the code below trap any error thrown?

    DO ON ERROR UNDO, THROW:
      
       oEJournalDatasetModel:TrackingChanges   = TRUE.
      
       oEJournalDatasetModel:EJournal:Create ().
       oEJournalDatasetModel:EJournal:TransNum   = piTransNum.
       oEJournalDatasetModel:EJournal:SaleDate   = pdtSaleDate.
       oEJournalDatasetModel:EJournal:PosTrans   = plcPosTrans.
       
       oEJournalDatasetModel:SaveChanges().
       
       /* Roger Blanchard/Osprey Retail Systems Dec 20, 2017 11:13:16 AM
        If we are here no error was thrown by the Dataset Model so let's RETURN TRUE
       */
      
       
       RETURN TRUE.
      
       CATCH err AS Progress.Lang.Error:
        
        LogManagerWrapper:WriteError(err).
        RETURN FALSE.
       END CATCH.
       
      END.
  2. Daniel van Doorn
    Daniel van Doorn avatar
    17 posts
    Registered:
    18 Jun 2018
    12 Feb 2020 in reply to Roger Blanchard
    Link to this post
    Hi Roger,

    What do you mean with PASOE shuts down? It crashes? Do you have  procore or a protrace?
    Which OE version are you using?

    You could trap the exceptions and throw an error instead. But I wonder if it makes any difference if the PASOE crashes.

    DO ON ERROR UNDO, THROW
        ON STOP UNDO, RETURN ERROR NEW MyOwnException
        ("A stop condition has been raised while initializing the scheduler") 
        ON QUIT UNDO, RETURN ERROR NEW MyOwnException
        ("A quit condition has been raised while initializing the scheduler"):   
    END.


  3. Roger Blanchard
    Roger Blanchard avatar
    381 posts
    Registered:
    29 Jun 2018
    12 Feb 2020 in reply to Daniel van Doorn
    Link to this post
    Believe it or not the end user rebooted the server.....

    This is not uncommon in our environment. Our software is in retail stores with an on premise server. You can train the users all you want if they want to reboot the server they will reboot the server.

    I can duplicate in my office by stopping PASOE while the front-end is saving the changes.
  4. Daniel van Doorn
    Daniel van Doorn avatar
    17 posts
    Registered:
    18 Jun 2018
    12 Feb 2020 in reply to Roger Blanchard
    Link to this post
    In that case, try the above code. Create your own exception or just to test use Progress.Lang.AppError 
  5. Roger Blanchard
    Roger Blanchard avatar
    381 posts
    Registered:
    29 Jun 2018
    12 Feb 2020 in reply to Daniel van Doorn
    Link to this post
    I am trying it right now...thanks.
  6. Roger Blanchard
    Roger Blanchard avatar
    381 posts
    Registered:
    29 Jun 2018
    12 Feb 2020 in reply to Daniel van Doorn
    Link to this post
    I was just looking at ServiceAdapter:SubmitData and it already has ON STOP and returning a StopConditionException. Shouldn't my code actually catch that exception?

    /* Mike Fechner, Consultingwerk Ltd. 01.05.2013
               Bug SCL-57: Handling of STOP-Conditions from the back end */
            DO ON STOP UNDO, RETURN ERROR NEW StopConditionException
                (SUBSTITUTE ("A stop condition has been raised while waiting for the backend.~nBackend component: &1"{&TRAN},
                             pcEntityName),
                 0):
                {Consultingwerk/OERA/callloop-begin.i}
                RUN VALUE(THIS-OBJECT:ServiceInterfacePath + "/proSIsubmit.p":U) ON hAppServer
                                          (pcEntityName,
                                           INPUT-OUTPUT DATASET-HANDLE hChangesDataset,
                                           INPUT-OUTPUT pcContext,
                                           INPUT-OUTPUT lcParameter,
                                           INPUT-OUTPUT DATASET-HANDLE phContextDataset BY-REFERENCE) .
                {Consultingwerk/OERA/callloop-end.i}
                IF hAppServer = SESSION:HANDLE THEN
                    ServiceManager:ProcessServiceLifeCycle() .
            END.
  7. Roger Blanchard
    Roger Blanchard avatar
    381 posts
    Registered:
    29 Jun 2018
    12 Feb 2020 in reply to Daniel van Doorn
    Link to this post
    Well, adding the DO ON ERROR UNDO, THROW
        ON STOP UNDO, RETURN ERROR NEW MyOwnException
        ("A stop condition has been raised while initializing the scheduler") 
        ON QUIT UNDO, RETURN ERROR NEW MyOwnException
        ("A quit condition has been raised while initializing the scheduler"): 

    made no difference. I am not sure what is going on. I have a workaround by checking the GUID returned from the server that is assigned in the CREATE trigger of the table. If it is blank the SaveChanges did not work.

    Any other ideas how to trap this?
  8. Mike Fechner
    Mike Fechner avatar
    319 posts
    Registered:
    14 Sep 2016
    13 Feb 2020 in reply to Roger Blanchard
    Link to this post
    The initially mentioned CATCH should stop all errors.

    STOP Conditions (hence not called errors) may be an exception - as the AVM reserves the right to ignore a DO ON STOP phrase. This has been changed in 11.7.5 as an actual tech-preview and in OE12 for real.You should look into the new feature documentation of OpenEdge is you are interested.

    But a lost AppServer connection should ??? not cause a STOP condition. That's an error.

    Did you check, that your reconnect on disconnect behavior works as it should?If my memories don't fool me, you have implemented a custom solution there.
  9. Roger Blanchard
    Roger Blanchard avatar
    381 posts
    Registered:
    29 Jun 2018
    13 Feb 2020 in reply to Mike Fechner
    Link to this post
    >> The initially mentioned CATCH should stop all errors.

    That is what I thought.

    >> STOP Conditions (hence not called errors) may be an exception - as the AVM reserves the right to ignore a DO ON STOP phrase. This has been changed in 11.7.5 as an actual tech-preview and in OE12 for real.You should look into the new feature documentation of OpenEdge is you are interested.

    If you are referring to -catchStop 1 we are using that.

    >> But a lost AppServer connection should ??? not cause a STOP condition. That's an error.

    That is what I thought...

    >> Did you check, that your reconnect on disconnect behavior works as it should?If my memories don't fool me, you have implemented a custom solution there.

    In our Back Office app we do have an OVERRIDE in our OspreyServiceAdapter for HandleDisconnection. However, it calls SUPER:HandleDisconnection to actually handle the reconnect/quit. If we do reconnect we do some cleanup of our legacy framework SA. 

    This particular app is using the SCL ServiceAdapter but we set the BehaviorOnDisconnect to Ignore. We want the app to handle the reconnect and that does appear to work. This app is a DB sync manager that syncs data between the OE backend and a local SQLite DB. The only UI is a notify icon and we do not want the reconnect dialog to appear. In this scenario I can actually call SaveChanges multiple times with no error thrown when PASOE is being shutdown.

    As a test I will set BehaviorOnDisconnect to QuitRetry and see what happens.


  10. Roger Blanchard
    Roger Blanchard avatar
    381 posts
    Registered:
    29 Jun 2018
    13 Feb 2020 in reply to Roger Blanchard
    Link to this post
    Using the CW ServiceAdapter with BehaviorOnDisconnect:QuitRetry makes no difference.

    When calling oEJournalDatasetModel:SaveChanges() while PASOE is being shutdown it will not throw an error and the record is not saved to the DB. The only way I can solve is by checking the value of the GUID field after SaveChanges as it is assigned on the backend. If it is blank then it was not saved to the DB
    Last modified on 13 Feb 2020 14:02 by Roger Blanchard
  11. Mike Fechner
    Mike Fechner avatar
    319 posts
    Registered:
    14 Sep 2016
    14 Feb 2020 in reply to Roger Blanchard
    Link to this post
    You are seeing this particularly while PASOE is being shut down? 

    Or also after if has been shut down? 
  12. Roger Blanchard
    Roger Blanchard avatar
    381 posts
    Registered:
    29 Jun 2018
    14 Feb 2020 in reply to Mike Fechner
    Link to this post
    From what I am seeing it is when PASOE is being shutdown.  Once it is completely shutdown the process knows it is disconnected. I will run another test to confirm.
  13. Mike Fechner
    Mike Fechner avatar
    319 posts
    Registered:
    14 Sep 2016
    14 Feb 2020 in reply to Roger Blanchard
    Link to this post
    In that case, it seems like the AVM does not raise an error when it should. We should get tech support involved. 

    I can try to find some time for repro it.
  14. Roger Blanchard
    Roger Blanchard avatar
    381 posts
    Registered:
    29 Jun 2018
    14 Feb 2020 in reply to Mike Fechner
    Link to this post
    I will remove my workaround a verify one more time that once PASOE is down we do not see the issue. Once I do that I will open a call with PTS.
  15. Roger Blanchard
    Roger Blanchard avatar
    381 posts
    Registered:
    29 Jun 2018
    14 Feb 2020 in reply to Mike Fechner
    Link to this post
    Well, I was incorrect. This is what I just tested.

    Started my DB syncmanager app which connected to PASOE just fine. Once connected and before trying to create records via DatasetModel class I shutdown PASOE and made sure it was stopped. I confirmed in the PASOE logs that the agent ended. I then started the process to create record using the DatasetModel class and all but 1 out of 100 did not make it to the server. It seemed to take about 30 seconds before an error was thrown.

    This process is constantly running. We are using Timer that fires every 30 seconds that will initiate our sync. At the top of the sync I use IF FrameworkSettings:AppServerManager:IsConnected ("Default") to check if we are connected. I do know in certain situations it may return true but I would expect if I continue and try to use the DatasetModel class to perform CRUD operations that an error would be thrown right away.
  16. Roger Blanchard
    Roger Blanchard avatar
    381 posts
    Registered:
    29 Jun 2018
    14 Feb 2020 in reply to Roger Blanchard
    Link to this post
    If I add a check if we are connected after the SaveChanges then we do know we are not connected. Should I have to do that? I would expect an error to be thrown



    DO ON ERROR UNDO, THROW:
     
       oEJournalDatasetModel:TrackingChanges   = TRUE.
      
       oEJournalDatasetModel:EJournal:Create ().
       oEJournalDatasetModel:EJournal:TransNum   = piTransNum.
       oEJournalDatasetModel:EJournal:SaleDate   = pdtSaleDate.
       oEJournalDatasetModel:EJournal:PosTrans   = plcPosTrans.
       
       oEJournalDatasetModel:SaveChanges().
       
       

    IF NOT Osprey.Framework.OspreyFrameworkSettings:AppServerServiceManager:IsConnected("") THEN
        UNDO, THROW NEW Progress.Lang.AppError("Not connected to Appserver",0). 


       
       /* Roger Blanchard/Osprey Retail Systems Dec 20, 2017 11:13:16 AM
        If we are here no error was thrown by the Dataset Model so let's RETURN TRUE
       */
       
        RETURN TRUE.
       
       
       CATCH err AS Progress.Lang.Error:
        LogManagerWrapper:WriteError(NEW AppError ("SendData caught error:", 0)).
        LogManagerWrapper:WriteError(err).
        RETURN FALSE.
       END CATCH.
       
      END.
      
      FINALLY:
       
       oEJournalDatasetModel:DatasetHandle:EMPTY-DATASET  ().
       
       LogManagerWrapper:WriteMessage("<Osprey.SQLite.EJournal.EJournalMapping  SendData>  End",
                                         NEW MessageSubSystem ("ORS_DBG") // we only want this to be logged if ORS_SQL is enabled )
                                         ).     
      END FINALLY.
  17. Roger Blanchard
    Roger Blanchard avatar
    381 posts
    Registered:
    29 Jun 2018
    15 Feb 2020 in reply to Roger Blanchard
    Link to this post
    I was expecting an error to be thrown in our situation but in looking at callloop-end.i that will never happen. If FALSE is returned from HandleDisconnection the app will exit. We do not want that which is why we set our DisconnectOption to Ignore. If we RETURN TRUE then this include will just suppress the error?

    Am I reading this correctly?

    &IF DEFINED (DotNetAccessible) NE 0 &THEN
                    LEAVE callloop .
                    CATCH callooperr AS Progress.Lang.SysError:
                   
                        IF ListHelper:EntryIsInList(STRING (callooperr:GetMessageNum(1)), "9326,9407,5490,14810,5451,5453":U) THEN DO:
                            IF NOT THIS-OBJECT:HandleDisconnection (pcPartition,
                                                                    ErrorHelper:FormattedErrorMessages (callooperr)) THEN DO:
                                System.Windows.Forms.Application:Exit () .
                                LEAVE callloop .
                            END .
                            ELSE DO:
                                ASSIGN hAppServer = hCachedServerHandle .
                            END.
                        END.
                        ELSE
                            UNDO, THROW callooperr .
                    END CATCH.
                END .
            &ENDIF
  18. Roger Blanchard
    Roger Blanchard avatar
    381 posts
    Registered:
    29 Jun 2018
    15 Feb 2020 in reply to Roger Blanchard
    Link to this post
    If I want an error to be thrown in this case when using BehaviorOnDisconnect = OptionsOnDisconnectEnum:Ignore.what is the best way to do this?

    I was thinking in our ServerAdapter add an OVERRIDE for SubmitData, InvokeMethod and InvokeTask where we just call SUPER to use all of the SCL functionality and then add a test to see if BehaviorOnDisconnect = OptionsOnDisconnectEnum:Ignore and we are not connected then throw an error.
  19. Roger Blanchard
    Roger Blanchard avatar
    381 posts
    Registered:
    29 Jun 2018
    20 Feb 2020 in reply to Mike Fechner
    Link to this post
    Hey Mike,

    Any thoughts on the best way to handle this? Using an OVERRIDE in our ServiceAdapter?
  20. Mike Fechner
    Mike Fechner avatar
    319 posts
    Registered:
    14 Sep 2016
    24 Feb 2020 in reply to Roger Blanchard
    Link to this post
    I'm afraid I have not been able to build a setup to reproduce and debug this yet.
20 posts, 0 answered