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, ...
Answered

How to handle error: An exception occurred when invoking the operation ?

(0) ShareShare
ReportReport
Posted on by 393
Hello,
 
What is the best approach of handling error : An exception occurred when invoking the operation ? Or to make it more clear message of what /really/ happened ?
I tried to add Catch Exception, but it seems still not enough explanation of what happened ? 
In then end, debugging is the only thing to do to know what is happening.
 
Is there any other way to firstly give a clear message of what is happening ? what is wrong or where. It is so good if the system can show on which class or object the error is.
 
Please help to advice. Thanks
I have the same question (0)
  • Suggested answer
    Layan Jwei Profile Picture
    8,097 Super User 2025 Season 2 on at
    Hi Teevo,
     
    Can you show us your code how are u catching the error? And what is the Operation exactly?
    Also can you give us an example of the error? I mean the details of the error when you debugged.
     
    But in general this way can catch most of errors:
     
     
    System.Exception ex; 
    try 
    {
         //Logic
     } 
    catch(ex)
     { 
          error(ex.Message);
     }
     
    Thanks,
    Layan Jweihan
    Please mark this answer as "Verified" if it solved your issue. In order to help others who will face a similar issue in the future
  • Suggested answer
    Kevin Xia Profile Picture
    Microsoft Employee on at
    Hi,
    Can you tell us why you need a more precise way to handle the problem, or you can show us a block of code that confuses you and let us show you what went wrong?
    Generally speaking, the "try catch" block catches the vast majority of errors and throws them, and the reason why you think it's not a real error is probably because of an error thrown by the system source code, so it's hard to understand it literally and find a solution.
    Best regards,
    Kevin
  • Suggested answer
    Bharani Preetham Peraka Profile Picture
    3,634 Moderator on at
    While catching exceptions, we basically make use of exception type of error. But in standard, some of the errors are not actually errors and those are warnings. So that is why we can't get clear error. It only states "update has been cancelled" something like this. So, while writing exception code, you should be careful what to exclude and what is not. Please send your code so that we can help you with best answer.
  • Teevo Profile Picture
    393 on at
    Hi Kevin / Bharani,
     
    Understand it cannot be too precise, but I expect the message is clear enough because I'm going to pass it through API. So some app outside the system can receive this error message. What I'm facing so far, some time there is an error but the message is blank, We don't know what happened until I tried to repeat the same action but manually inside D365.
     
    The code however contain more than 1 class, so maybe this was the issue. Which is in illustration will be something like this:
    Class A
    {
        public str B()
        {
    
           try
               {
                   ......
                   classC = new classC();
                   D = classC.process();
               }
           catch (Exception::CLRError)
                {
                   .......
                }
            catch (Exception::Error)
                {
                   .......
                }
            
            return B;
    
        }
    }
    
    
    Class classC()
    {
    
        public str D()
        {
            try  // 1st-level try
            {
                   ......
                   salestable.insert();
                   while select lines
                   {
                      try
                      {
                           ........ 
                           salesline.insert();
                      }
                      catch (Exception::Deadlock)
                      {                   
                              if (xSession::currentRetryCount() >= #RetryNum)
                              {
                                  throw Exception::Deadlock;
                              }
                              else
                              {
                                   retry;
                              }
                        
                       }
                       catch (Exception::UpdateConflict)
                       {                   
                              if (appl.ttsLevel() == 0)
                              {
                                    if (xSession::currentRetryCount() >= #RetryNum)
                                    {
                                         throw Exception::UpdateConflictNotRecovered;
                                    }
                                    else
                                    {
                                         retry;
                                     }
                               }
                               else
                               {
                                     throw Exception::UpdateConflict;
                                } 
                       }
                       catch(Exception::DuplicateKeyException)
                       {                   
                             if (appl.ttsLevel() == 0)
                             {
                                    if (xSession::currentRetryCount() >= #RetryNum)
                                    {
                                          throw Exception::DuplicateKeyExceptionNotRecovered;
                                    }
                                    else
                                    {
                                          retry;
                                    } 
                             }
                             else
                             {
                                    throw Exception::DuplicateKeyException;
                             }
                        }
                        catch (Exception::Error)
                        {
                   
                              container   infoData = infolog.infologData();
                              Str1260     errorTxt;
    
                              for (int i = 1; i <= conLen(infoData); i++)
                              {
                                    container internalInfoData = conPeek(infoData, i);
    
                                    if (errorTxt == "")
                                    {
                                        errorTxt =  conPeek(internalInfoData, 2);
                                    }
                                    else
                                    {
                                        errorTxt += ";" + conPeek(internalInfoData, 2);
                                    }
                                }
                                errorMessage = errorTxt;
                                throw Error(errorMessage);
                           }
                       } // end while select
               } // end 1st-level try 
               catch (Exception::Deadlock)
               {          
                     if (xSession::currentRetryCount() >= #RetryNum)
                     {
                          throw Exception::Deadlock;
                     }
                     else
                     {
                           retry;
                     }
               
                }
                catch (Exception::UpdateConflict)
                {          
                
                      if (appl.ttsLevel() == 0)
                      {
                            if (xSession::currentRetryCount() >= #RetryNum)
                            {
                                throw Exception::UpdateConflictNotRecovered;
                            }
                            else
                            {
                                retry;
                            }
                      }
                      else
                      {
                           throw Exception::UpdateConflict;
                      }
                 }
                 catch(Exception::DuplicateKeyException)
                 {          
                
                      if (appl.ttsLevel() == 0)
                      {
                            if (xSession::currentRetryCount() >= #RetryNum)
                            {
                                 throw Exception::DuplicateKeyExceptionNotRecovered;
                            }
                            else
                            {
                                 retry;
                            }
                       }
                       else
                       {
                           throw Exception::DuplicateKeyException;
                       }
                  }
                  catch (Exception::Error)
                  {
                   
                        container   infoData = infolog.infologData();
                        Str1260     errorTxt;
    
                        for (int i = 1; i <= conLen(infoData); i++)
                        {
                              container internalInfoData = conPeek(infoData, i);
    
                              if (errorTxt == "")
                              {
                                  errorTxt =  conPeek(internalInfoData, 2);
                              }
                              else
                              {
                                  errorTxt += ";" + conPeek(internalInfoData, 2);
                               }
                         }
                         errorMessage = errorTxt;
                         throw;
                   }
        	      
                   return D;	
          }
    }
    
    I'm wondering how to make this correctly ?
    Class A is the one who will be passing the message to outside system (API). But as mentioned, at some of the time when we're doing test, there will be a blank error message which then make us confuse what is the error this time.
     
  • Martin Dráb Profile Picture
    237,795 Most Valuable Professional on at
    My guess it that your code fails to populate errorMessage variable and throw error(errorMessage) is then actually throw error(''). Debugging will tell you more about when it happens.
     
    Note that in the outer catch, all the code for getting the message is useless, because you never use the value of errorMessage variable. By the way, I don't see a reason for having this code duplicated. If you eliminate the duplication, the risk of forgetting to change all occurrences will disappear.
     
    Another problem in your code is that it takes all messages in infolog, even those related to your code in the try block.
     
    I wonder what was the intention of the code. If you want a message of an exception, you can get it from the exception, can't you?. And if you want all infolog messages, what's the point of duplicating them by throwing them as an extra exception? You can simply collect infolog messages (you already have the code) and send them to the external system.
  • Martin Dráb Profile Picture
    237,795 Most Valuable Professional on at
    I think we can simplify your code (for the current discussion) to something like this:
    class A
    {
        public void B()
        {
            System.Exception ex;
    
            try
            {
               new ClassC().process();
            }
            catch (ex)
            {
               ... do something with ex ...
            }
    
            return '';
        }
    }
    
    
    class ClassC()
    {
        public void process()
        {
            try
            {
                throw error("Test error");
            }
            catch (Exception::Error)
            {
                container infoData = infolog.infologData();
                str errorTxt;
    
                for (int i = 1; i <= conLen(infoData); i++)
                {
                    container internalInfoData = conPeek(infoData, i);
    
                    if (errorTxt == "")
                    {
                        errorTxt =  conPeek(internalInfoData, 2);
                    }
                    else
                    {
                        errorTxt += ";" + conPeek(internalInfoData, 2);
                    }
                }
    
                throw error(errorTxt);
            }
        }
    }
  • Teevo Profile Picture
    393 on at
    Hi Martin,
     
    Thanks, I will try this. Just to make sure, so it means if I have process like Header and details (lines), like in Class C, I do not need to put another Try..Catch() in the while..select of the lines process. So only 1 Try..Catch() at the header level. This is what you are pointing why there is seems like a duplicate ? 
    I'm sorry, that is because I look into several blogs, and tried to summarize my self, so basically it is not the best practice.
     
    Thanks.
  • Verified answer
    Martin Dráb Profile Picture
    237,795 Most Valuable Professional on at
    Yes, your outer catch currently does nothing, which is likely as bug. It seems that your intention was duplicating the logic of the inner catch, which is not only unnecessary, but it would add all messages to infolog again, which would be another bug, in my opinion. You already duplicate all messages and if you did it again, you'd have all messages in infolog four times.
     
    In short, you need catch statements at the place where you want to handle exceptions, not necessarily where they're thrown. I see you already have a catch statement in class A, so maybe you don't need any in ClassC at all.

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 660 Most Valuable Professional

#2
André Arnaud de Calavon Profile Picture

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

#3
Sohaib Cheema Profile Picture

Sohaib Cheema 307 User Group Leader

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans