web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Suggested Answer

catch exception types

(2) ShareShare
ReportReport
Posted on by 1,965
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:
I have the same question (0)
  • Suggested answer
    Martin Dráb Profile Picture
    237,874 Most Valuable Professional on at
    The decision depends on what you want to catch. You may want to catch X++ errors, all X++ exceptions (e.g. DuplicateKeyException, not just errors), both X++ exceptions and CLR exceptions...
     
    In your example, the question is what situations you want to handle. For example, if you want to retry the insert on DuplicateKeyException, you shouldn't use any of the four ways you mentioned; you should catch Exception::DuplicateKeyException instread. Or maybe you don't want to handle any exception at all and you'll use no catch clause; you'll simply let the process fail (and the exception returned to the caller) if the insert throws an exception.
  • .. Profile Picture
    1,965 on at
    Hi Martin,

    in the response contract class of the custom service, I return parmError() in which i return the error message that occurred. (so i can't remove the try catch)

    So for example, if i'm inserting into the country table, and I don't provide country regionId in the request of the service, an error is thrown.

    I tried to catch it by catch(Exception::Error) but it didn't catch it, isn't this an x++ exception? not sure why it didn't catch it
    then i tried to catch it with CLR, it didn't catch it
    i tried to catch it with System.Exception, it entered the catch but ex.Message didn't return anything, it seems i will need to get the error from the infolog.
    also i tried to use the general catch, and it entered it, but again i need to write code to get the error and pass it to parmError.


    1. So in my case, shall i use general catch or system.Exception?
    2. what is sth that the general catch catches but system.Exception doesn't?
    3. can u give me an example on when to use each one of the four( catch, catch exception::Error, catch system.Exception, and catch CLR?
    4. for the deadlock, doesn't the general catch catches it already?
  • Martin Dráb Profile Picture
    237,874 Most Valuable Professional on at
    If you aren't aware of it, note that custom service already collect information about exceptions and return it in a special failure contract. Consider simply using the standard solution before building something custom.
     
    If your catch clause doesn't catch error exceptions, a common reason is that your code is inside a DB transaction. Look at ttslevel in debugger; you'll likely find that the operation is indeed wrapped in a transaction.
     
    If you want to know the type of the exception, look at the type of the object inside $exception value in debugger, or the variable you use when catching System.Exception.
     
    Regarding your numbered questions:
    1. There isn't an universal answer. For example, if you want to access properties of CLR exceptions and not just infolog messages, the plain catch wouldn't work for you.
    2. Both catch all exceptions.
    3. You already seem to know how to do it, therefore repeating it would be a waste of time for both of us.
    4. Yes.
  • .. Profile Picture
    1,965 on at
    Hi Martin,

    1. What's the standard failure contract?

    2. When you said "If your catch clause doesn't catch error exceptions, a common reason is that your code is inside a DB transaction" Do you mean that catch Exception::Error should have catched it but because there is transaction it didn't work? or do you mean that System.Exception ex was null because of transaction
    because as i said, it didn't enter the exception error catch, it only entered that System.Exception catch but ex was null

     
    3. what does CLR mean? what kind of errors does it catch?
    4. what's the difference between CLR catch and System.Exception catch?
  • Martin Dráb Profile Picture
    237,874 Most Valuable Professional on at
    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.
  • .. Profile Picture
    1,965 on at
    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
    237,874 Most Valuable Professional on at
    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,965 on at
    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
    237,874 Most Valuable Professional on at
    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,965 on at
    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?

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

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Martin Dráb Profile Picture

Martin Dráb 646 Most Valuable Professional

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 529 Super User 2025 Season 2

#3
Sohaib Cheema Profile Picture

Sohaib Cheema 285 User Group Leader

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans