Skip to main content

Notifications

Announcements

No record found.

Finance | Project Operations, Human Resources, ...
Suggested answer

catch exception types

(2) ShareShare
ReportReport
Posted on by 1,273
Hi,

When to use the following four?

generic catch
catch(Exception::Error)
catch system.Exception
catch CLR

I mean how to decide which one to use?

And for example, if let's say i created a custom service that inserts records into tables, which catch should I use?
Categories:
  • Martin Dráb Profile Picture
    Martin Dráb 230,476 Most Valuable Professional on at
    catch exception types
    Your first point suggests that you're asking about different code than what you've shared. Please give us the one that you want to discuss. Then show us not only code catching the exception, but also the code raising it (so we know what exception was thrown).
     
    Regarding 2, please use the debugger to find out what happens in your code. You see that you have no idea about what happenned if you ignore code and check at the output only. 
  • .. Profile Picture
    .. 1,273 on at
    catch exception types
    Hi Martin,

    Did you get a chance to see my reply?
  • .. Profile Picture
    .. 1,273 on at
    catch exception types
    Hi Martin,

    the ttslevel auto variable increased to 1 when i called partyPostalAddress.insert(). when the error was thrown in this method due to missing country, the generic catch in my service class was called and inside it the ttslevel became 0
     
    class Service1
    {
        public ResponseContract create(RequestContract _request)
        {
            System.Exception            ex;
    
            int startLine = infologLine();
    
            ResponseContract response = new ResponseContract();
    
            if(_request)
            {
                try
                {
                    if(this.validate(_request))
                    {
                          DirPartyLocationPostalAddressV2Entity partyPostalAddressEntity;
                         // logic
                         partyPostalAddressEntity.insert();
                    }
                    else
                    {
                        throw Exception::Error;
                    }
                }
                //catch(Exception::Error)
                //{
                //    response.parmErrorMessage(this.getErrorMessage(startLine));
                //}
                //catch(ex)
                //{
                //    response.parmErrorMessage(ex.Message);
                //}
                catch
                {
                    resContract.parmErrorMessage(this.getErrorMessage(startLine));
                }
            }
    
            return resContract;
        }
    }

    I hope it's now clearer, so i will repeat my questions:

    1. before i commented out the catch(ex) and catch(Exception::Error):
    1a. why catch(Exception::Error) wasn't called when inserting an address?
    1b. and why catch System.Exception was called but ex variable was null?

    2. If i will use the standard exception in custom services and remove the try and catch:
    As i said when i throw an error with the word "test", i was able to see it

    but when the address error was thrown, the full message didn't appear, why????


    but with try and catch, i was able to get the message from the infolog
  • Martin Dráb Profile Picture
    Martin Dráb 230,476 Most Valuable Professional on at
    catch exception types
    I saw that, but it's not relevant. We're talking about ttslevel at the place where you're catching exceptions. Your screenshot shows that there is a transaction somewhere, but it not whether it was started inside or outside try block.
     
    Remember that we're talking about the exception catching. Also, you can find some details about exception handling in transactions in the documentation I shared with you ( X++ exception handling > Exceptions inside transactions).
  • .. Profile Picture
    .. 1,273 on at
    catch exception types
    Hi Martin,

    Yes I did, in the 4th reply, i shared a screenshot, where it shows that ttslevel is 1 when the insert method of the entity gets called. I will share it again


    is this helpful to answer my previous three questions or do you need more info?
  • Martin Dráb Profile Picture
    Martin Dráb 230,476 Most Valuable Professional on at
    catch exception types
    There are too many unknowns. For example, you still haven't commented on the value of ttslevel when you're trying to catch the exception.
  • .. Profile Picture
    .. 1,273 on at
    catch exception types
    Hi Martin,

    1. You mean throw an error without try catch? , I got the test error here

    But in my case, without try catch, here's the output (it doesn't show the full message), how to show the actual error without try and catch?

    with try catch, here's the output (it shows the actual error) because i get it from the infolog
     
    2a. No i don't get the error from the validate (the validate only validates the customer), i get the error when i insert an address without providing country to the request (it fails on this line partyPostalAddressEntity.insert())
    So in the service class after the validate method, i call a class that has this code below
    class PostalAddress
    {
        /// <summary>
    
        public LogisticsPostalAddressRecId createAddress(PostalAddressContract _postalAddress, CustAccount _custAccount = '')
        {
            LogisticsPostalAddressRecId     postalAddressRecId;
    
            try
            {
                CustTable custTable = CustTable::find(_custAccount);
                if(custTable)
                {
                    DirPartyTable  dirPartyTable    = DirPartyTable::findRec(custTable.Party);
                    if(_postalAddress)
                    {
                        DirPartyLocationPostalAddressV2Entity partyPostalAddressEntity;
    
                        partyPostalAddressEntity.PartyNumber        =  dirPartyTable.PartyNumber;
                        partyPostalAddressEntity.Street             = _postalAddress.Street();
                        partyPostalAddressEntity.City               = _postalAddress.City();
                        partyPostalAddressEntity.County             = _postalAddress.County();
                        partyPostalAddressEntity.State              = _postalAddress.State();
                        partyPostalAddressEntity.CountryRegionId    = _postalAddress.CountryRegionId();
                        partyPostalAddressEntity.ZipCode            = _postalAddress.PostCode();
                        partyPostalAddressEntity.Roles              = LogisticsLocationRoleType::Delivery
                        partyPostalAddressEntity.Description        = _postalAddress.LocationName();
     
    
                        partyPostalAddressEntity.insert();  // it fails here
    
    
                        LogisticsPostalAddress logisticsPostalAddress = LogisticsPostalAddress::findByLocation(partyPostalAddressEntity.RecId);
                        postalAddressRecId = logisticsPostalAddress.RecId;
                    }
             
                }
            }
            catch(Exception::Error)
            {
                throw error('Error when creating address');
            }
            
            return postalAddressRecId;
        }
    
    }


    2b. i commented out the catch(ex) and catch(Exception::Error), here's the full code

    So why catch(Exception::Error) wasn't called when inserting an address?
    and why catch System.Exception was called but ex variable was null?
                //catch(Exception::Error)
                //{
                //    response.parmErrorMessage(this.getErrorMessage(startLine));
                //}
                //catch(ex)
                //{
                //    response.parmErrorMessage(ex.Message);
                //}
                catch
                {
                    response.parmErrorMessage(this.getErrorMessage(startLine));
                }
     
     
  • Martin Dráb Profile Picture
    Martin Dráb 230,476 Most Valuable Professional on at
    catch exception types
    1. Change your code to mere throw error("TEST"), call the custom service and see what you get.
     2. These are warning messages in infolog, not exceptions.
    2a. You didn't tell us what code you have in validate(), but it sounds like you get validation failures and validate() return false, without having any exception raised. If it's case, you can't catch an exception simply because there isn't any.
    2b. I can't comment on it. There is no catch of System.Exception in your code and I don't know what code you call in the try block.
  • .. Profile Picture
    .. 1,273 on at
    catch exception types
    Hi Martin,

    1. I still don't get what contract are u referring to, can you please provide an example? as currently this is what i did:
    class Service1
    {
        public ResponseContract create(RequestContract _request)
        {
            System.Exception            ex;
    
            int startLine = infologLine();
    
            ResponseContract response = new ResponseContract();
    
            if(_request)
            {
                try
                {
                    if(this.validate(_request))
                    {
                         // logic
                    }
                    else
                    {
                        throw Exception::Error;
                    }
                }
                catch
                {
                    resContract.parmErrorMessage(this.getErrorMessage(startLine));
                }
            }
    
            return resContract;
        }
    }
    2. I still don't get it, for those errors:

    2a.  why catch(Exception::Error) wasn't called when inserting an address?
    2b: why catch System.Exception was called but ex variable was null?
  • Martin Dráb Profile Picture
    Martin Dráb 230,476 Most Valuable Professional on at
    catch exception types
    1. It's the contract used by standard F&O to report exceptions in custom services.
    2. I mean that you can't catch most type of exceptions there. Please read the documentation for more details: X++ exception handling > Exceptions inside transactions.
    3. It stands for Common Language Runtime. It used to be used for catching exceptions in .NET libraries called via .NET Interop (aka CLR Interop). In F&O, you can catch System.Exception, which gives you the exception object. It's much easier than catching the CLR exception and then trying to find the exception object, as used to be needed in older versions.
    4. Already covered above.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Congratulations 2024 Spotlight Honorees

Kudos to all of our 2024 community stars! 🎉

Meet the Top 10 leaders for December

Congratulations to our December super stars! 🥳

Start Your Super User Journey

Join the ranks of our community heros! 🦹

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,784 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,476 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Product updates

Dynamics 365 release plans