CSLA .NET

Vibrant discussion about CSLA .NET and using the framework to build great business applications.

Forum has moved

New location: CSLA .NET forum


CSLA .NET Resources:
  • CSLA .NET forum
  • CSLA .NET home page
  • Unable to catch exception with async dataportal call (async/await)

    rated by 0 users
    Not Answered This post has 0 verified answers | 2 Replies | 1 Follower

    Not Ranked
    3 Posts
    Chit Swe posted on Fri, Mar 20 2015 4:31 AM

    Hello,

     

    I am developing window form application by using  CSLA 4.5.501.0 with visual studio 2013 and dot net 4.0. I can successfully fetch data from remote dataportal. 

     

    The following is static factory method from BusinessBase class.

     

     public static async Task<PurchaseHeader> GetPurchaseVoucher(string prefix, long serial)

            {

                VoucherNoCriteria criteria = new VoucherNoCriteria()

                {

                    Prefix = prefix,

                    Serial = serial

                };

                PurchaseHeader purchase = await DataPortal.FetchAsync<PurchaseHeader>(criteria);

                purchase.MarkOld();

                return purchase;

         }

     

    ----------------------------------------------------------------------------------

     

    private async void SearchPurchase(VoucherNo vno) {

                try

                {

                    this.Cursor = Cursors.WaitCursor;

     

                    if (vno != null)

                    {

                        this.ultraStatusBar1.Text = string.Format("Loading purchase voucher ({0}-{1}).", vno.Prefix, vno.Serial);

                        this.purchase = await PurchaseHeader.GetPurchaseVoucher(vno.Prefix, vno.Serial);

                        BindData();

                        commandToolBar1.SetSavedState();

                        this.ultraStatusBar1.Text = string.Format("Done loading purchase voucher ({0}-{1}).", vno.Prefix, vno.Serial);

                    }

                }

                catch (Csla.DataPortalException ex) {

     

                    if (ex.BusinessException is RecordNotFoundException)

                    {

                        UltraMessageBoxManager.Show("Purchase voucher cannot found.", "Purchase", MessageBoxButtons.OK, MessageBoxIcon.Information);

                    }

                    else if (ex.BusinessException != null)

                    {

                        UltraMessageBoxManager.Show("Fail to load purchase voucher\n" + ex.BusinessException.Message, "Purchase", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    } 

                    this.ultraStatusBar1.Text = "Ready";

                }

                catch (Exception ex)

                {

                    UltraMessageBoxManager.Show("Fail to load purchase voucher\n" + ex.Message, "Purchase", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    this.ultraStatusBar1.Text = "Ready";

                }

                finally {

                    this.Cursor = Cursors.Default;

                }

            }

     

     

     

    But if awaiting  async dataportal call throw exception,  catch block is unable to catch exception and TargetInvocationException is throw at Application.Run() method in Program.cs.

     

    How can I handle exception in this case.

    All Replies

    Top 10 Contributor
    2,279 Posts

    Hi, 

    When you use async methods that return a Task you must catch System.AggregateException that may contain several exceptions. One of these exception will be a Csla.DataPortalException.

    See this article: https://msdn.microsoft.com/en-us/library/dd537614(v=vs.110).aspx

    Jonny Bekkum, Norway CslaContrib Coordinator

    Not Ranked
    3 Posts
    Chit Swe replied on Sun, Mar 22 2015 10:57 PM

    As you suggested, I changed my code.

    private async void SearchPurchase(VoucherNo vno) {

                try

                {

                    this.Cursor = Cursors.WaitCursor;

                    if (vno != null)

                    {

                        Program.MainForm.ShowLoading(string.Format("Loading purchase voucher ({0}-{1}).", vno.Prefix, vno.Serial));

                        this.purchase = await PurchaseHeader.GetPurchaseVoucherAsync(vno.Prefix, vno.Serial);

                        BindData();

                        commandToolBar1.SetSavedState();

                        Program.MainForm.HideLoading(string.Format("Done loading purchase voucher ({0}-{1}).", vno.Prefix, vno.Serial));

                    }

     

                }

                catch (AggregateException ex)

                {

                    ex.Handle(x => { HandleException("Failed to load purchase voucher", x); return true; });

                }

                catch (Csla.DataPortalException ex)

                {

                    if (ex.BusinessException is RecordNotFoundException)

                    {

                        Program.MainForm.HideLoading("Ready");

                        UltraMessageBoxManager.Show("Purchase voucher cannot found.", "Purchase", MessageBoxButtons.OK, MessageBoxIcon.Information);

                    }

                    else if (ex.BusinessException != null)

                    {

                        HandleException("Fail to load purchase voucher",ex);

                    } 

                }

                catch (Exception ex)

                {

                    UltraMessageBoxManager.Show("Fail to load purchase voucher\n" + ex.Message, "Purchase", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    Program.MainForm.HideLoading("Ready");

                }

                finally {

                    this.Cursor = Cursors.Default;

                }

            }

     

    Here I found two interesting things.

    1.If exception is thrown by server side code (in my case, I throw my custom exception 'RecordNotFoundException'), it pass to the client and I can successfully catch the exception (by DataPortalException catch block not by AggregateException catch block) that return from server as expected.

    2.If exception is throw by client code (in my case, I unplugged network cable from my computer  to throw exception), the exception cannot be catch as expected and throw at Application.Run() method in Program.cs.

     

    As workaround, I catch this kind of user unable to handle exception by using Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException) and 

    attach event handler 

    Application.ThreadException += Application_ThreadException.

    But it is not perfect. Because I cannot perform required action if communication is failed.

     

    Thanks

    Chit Swe

    Page 1 of 1 (3 items) | RSS

    Copyright (c) 2006-2014 Marimer LLC. All rights reserved.
    Email admin@lhotka.net for support.
    Powered by Community Server (Non-Commercial Edition), by Telligent Systems