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

Doing a load performance test for a custom service

(0) ShareShare
ReportReport
Posted on by 465

Hi,

I created a soap custom service, that creates customized orders in d365FO . And i wanted to do a simple  load performance test using soap UI.

I did the load test using 20 threads for 1 minute.

What i noticed is sometimes  all orders get created but if i try another time 4 or 6 might fail with the following error from soap UI:

<h2>502 - Web server received an invalid response while acting as a gateway or proxy server.</h2>
<h3>There is a problem with the page you are looking for, and it cannot be displayed. When the Web server (while acting as a gateway or proxy) contacted the upstream content server, it received an invalid response from the content server.


What could the issue be? could it be from my service code?





I have the same question (0)
  • André Arnaud de Calavon Profile Picture
    300,917 Super User 2025 Season 2 on at

    Hi D365FO user,

    Can you be more specific about the situation? I do assume when you get the error, that the order will not be created. However, you mentioned that all do get created. Can you clarify this?

    Initially, you can check information on the internet about the 502 error. Then you can check if you can solve it yourself.

    Also note that sometimes you can get an error 429. This is new from the prioritized based throttling. I do hope your service is prepared to do a retry in case of this error. More info: Priority-based throttling - Finance & Operations | Dynamics 365 | Microsoft Docs

  • D365FO user Profile Picture
    465 on at

    Hi Andre,

    No i mean i did the performance more the than once. the first two times i did it, i got no error and everything got created.

    However, the third time i did it, it created let's say 80 records and it said that 4 failed with the error i showed above ( these 4 didn't get created)

    1. So i got confused why would the third test fail? could it be because of my code?

    Here's the code:

    class XXOrderService
    {
       
        public XXResContract getDetails(XXReqContract _Ids)
        {
            XXDetailLineResContract    responseLine;
            XXResContract              orderCreationResponse;
            
            XXDetailResContract        resultSet  = new XXDetailResContract();
            
            XXOrderCreationService     orderCreationService    = new XXOrderCreationService();
    
            int                                     startLine = infologLine()   1;
    
            AmountCur                               total       = 0;
            
            str                                     errorMsg;
    
            try
            {
                if(_Ids)
                {
                    orderCreationResponse = orderCreationService.createOrder(_Ids,true);  // LOOK AT THIS METHOD PLEASE
                    
                    if(orderCreationResponse && orderCreationResponse.ErrorCode() == null)
                    {
                        Table1                  table1;
                        Table2                  table2;
                        Table3                  table3;
    
                        select table1 where table1.Id == orderCreationResponse.Id();
                        if(table1)
                        {
    
                            while select table2 where table2.Id == orderCreationResponse.Id()
                            outer join table3 where table3.Id2 == table2.Id2
                            {
                                if(lineNum != rentLine.LineNum)
                                {
                                    responseLine = new XXDetailLineResContract();
                                    responseLine.ItemId(table2.ItemId);
                                    responseLine.Name(table2.Name);
                                    responseLine.Qty(rentLine.Qty);
    
                                    lineNum = table2.LineNum;
    
                                    response.addEnd(responseLine);
    
                                }
    
                                if(table3)
                                {
                                    total  = (table3.Percent * table2.LineAmount)/100;
                                }
    
                            }
    
                        }
    
    
                        resultSet.DetailLineResContract(response);
                        resultSet.Total(total);
    
                    }
                    else
                    {
                        resultSet.ErrorCode(orderCreationResponse.ErrorCode());
                        resultSet.ErrorMessage(orderCreationResponse.ErrorMessage());
                    }
                }
    
            }
            catch(Exception::Error)
            {
                resultSet = new XXDetailResContract();
                errorMsg = '';
              
                SysInfologEnumerator sysInfologEnumerator = SysInfologEnumerator::newData(infolog.copy(startLine,Global::infologLine()));
                while (sysInfologEnumerator.moveNext())
                {
                    switch (sysInfologEnumerator.currentException())
                    {
                        case Exception::Error:
                            errorMsg  = sysInfologEnumerator.currentMessage()   '\n';
                            break;
                    }
                }
                resultSet.ErrorCode('AX_Error');
                resultSet.ErrorMessage(errorMsg);
    
            }
            catch(Exception::DuplicateKeyException)
            {
                resultSet = new XXDetailResContract();
                errorMsg = '';
    
                SysInfologEnumerator sysInfologEnumerator = SysInfologEnumerator::newData(infolog.copy(startLine,Global::infologLine()));
                while (sysInfologEnumerator.moveNext())
                {
                    switch (sysInfologEnumerator.currentException())
                    {
                        case Exception::Error:
                            errorMsg  = sysInfologEnumerator.currentMessage()   '\n';
                            break;
                    }
                }
                resultSet.ErrorCode('AX_DuplicateKey');
                resultSet.ErrorMessage(errorMsg);
    
            }
            
            catch
            {
                resultSet = new XXDetailResContract();
    
                SysInfologEnumerator sysInfologEnumerator = SysInfologEnumerator::newData(infolog.copy(startLine,Global::infologLine()));
                while (sysInfologEnumerator.moveNext())
                {
                    switch (sysInfologEnumerator.currentException())
                    {
                        case Exception::Info:
                            resultSet.ErrorCode('AX_Info');
                            resultSet.ErrorMessage(sysInfologEnumerator.currentMessage());
                            break;
                        case Exception::Warning:
                            resultSet.ErrorCode('AX_Warning');
                            resultSet.ErrorMessage(sysInfologEnumerator.currentMessage());
                            break;
                    }
                }
    
            }
    
            
            return resultSet;
        }
    
       
    
    
    }



    public XXOrderCreationResContract createOrder(XXOrderCreationReqContract _orderReq, NoYesId _retrive = false)
        {           
            List                            orderLines      = new List(Types::Class);
    
            XXOrderCreationResContract     resContract     = new XXOrderCreationResContract();
            
            Table1                         table1;
    
            int                             currentLine;
            int                             startLine;
    
            str                             errorMsg;
    
            str                             stage = '';
            boolean                         valid = true;
    
    
            try
            {
                orderLines = _orderReq.OrderLines();
                if(!orderLines||!orderLines.elements())
                {
                    throw error('No line records found for this order');
                }
    
    
    
    
                if(valid)
                {
    
    
                    ttsbegin;
                    XXCreate create = new XXCreate();
    
    
                    table1 = create.create(_orderReq, orderLines);
    
                    this.updateTable1(table1, _orderReq);
                    ttscommit;
    
    
                    if(!_retrive)
                    {
                        if(_orderReq.Auto())
                        {
    
                            const int retryCount = 2;
    
                            this.confirmOrder(table1);
    
                            try
                            {   
                                ttsbegin;
                                this.auto(table1);
                                ttscommit;
                            }
                            catch
                            {
                                if(xSession::currentRetryCount() >= retryCount)
                                {
                                    if(table1.Id)
                                    {
                                        this.cancelOrder(table1);
                                    }
    
                                    errorMsg = '';
                                    for (currentLine = startLine   1; currentLine <= Global::infologLine(); currentLine  )
                                    {
                                        errorMsg  = stage   ' : '   infolog.text(currentLine)   '\n';
                                    }
                                    startLine=currentLine-1;
    
                                    resContract= new XXOrderCreationResContract();
                                    resContract.Id(table1.Id);
                                    resContract.Id3(_orderReq.Id3());
                                    resContract.ErrorCode('AX_Error');
                                    resContract.ErrorMessage(errorMsg);
                                }
                                else
                                {
                                    retry;
                                }
                            }
    
                        }
                        else if(_orderReq.Status() == enum2Str(Status::Approved))
                        {
                            this.confirmOrder(table1);
                        }
    
                    }
    
                    resContract.Id(table1.Id);
                    resContract.Id3(_orderReq.Id3());
                }
            }
            catch(Exception::Error)
            {
                if(table1.Id && !_retrive)
                {
                    this.cancelOrder(table1);
                }
    
                errorMsg = '';
                for (currentLine = startLine   1; currentLine <= Global::infologLine(); currentLine  )
                {
                    errorMsg  = stage   ' : '   infolog.text(currentLine)   '\n';
                }
                startLine=currentLine-1;
    
                resContract= new XXrderCreationResContract();
                resContract.Id(table1.Id);
                resContract.Id3(_orderReq.Id3());
                resContract.ErrorCode('AX_Error');
                resContract.ErrorMessage(errorMsg);
            }
            catch(Exception::DuplicateKeyException)
            {
                if(table1.Id && !_retrive)
                {
                    this.cancelOrder(table1);
                }
    
                errorMsg = '';
                for (currentLine = startLine   1; currentLine <= Global::infologLine(); currentLine  )
                {
                    errorMsg  = stage   ' : '  infolog.text(currentLine)   '\n';
                }
                startLine=currentLine-1;
    
                resContract= new XXrderCreationResContract();
                resContract.Id(table1.Id);
                resContract.Id3(_orderReq.Id3());
                resContract.ErrorCode('AX_Error');
                resContract.ErrorMessage(errorMsg);
            }
            catch
            {
                if(table1.Id && !_retrive)
                {
                    this.cancelOrder(table1);
                }
    
                errorMsg = '';
                for (currentLine = startLine   1; currentLine <= Global::infologLine(); currentLine  )
                {
                    errorMsg  = stage   ' : '  infolog.text(currentLine)   '\n';
                }
                startLine = currentLine - 1;
    
                resContract= new XXrderCreationResContract();
                resContract.Id(table1.Id);
                resContract.Id3(_orderReq.Id3());
                resContract.ErrorCode('AX_Error');
                resContract.ErrorMessage(errorMsg);
            }
    
            return resContract;
        }

    2. how can i enhance the code? is there any possible dangers?

    3. I don't think the setup is made for priority throttling. But in case it was how should i enhance the code to handle it. can you please explain?

    4. should i catch system.exception errors?

  • Suggested answer
    zhifeng Profile Picture
    on at

    Hello,

    Normally you will see too many requests if it is cased by throttled and you can add retry to handle  429 error. Also you can query throttling events on the Lifecycle Services Monitoring page.

    https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/priority-based-throttling

  • D365FO user Profile Picture
    465 on at

    Hi kevin,

    But i didnt do the setup for throttling. So what would be the reason i'm geting 502? is it because of my code?

  • zhifeng Profile Picture
    on at

    Priority-based throttling is enabled by default starting in Dynamics 365 Finance version 10.0.19. And you can verify LCS raw log during that period to see if there are errors.

  • D365FO user Profile Picture
    465 on at

    Hi Kevin,

    but what would happen if i don't fill it with the setup required? how is it going to work?

  • Suggested answer
    André Arnaud de Calavon Profile Picture
    300,917 Super User 2025 Season 2 on at

    If you don't do the setup, there is no priority, but there is still a throttling.

    See also the FAQ: docs.microsoft.com/.../throttling-faq

  • D365FO user Profile Picture
    465 on at

    Hi andre,

    How can i catch this 429 error in my custom service?

    Could the 502 error be because of this one?

  • André Arnaud de Calavon Profile Picture
    300,917 Super User 2025 Season 2 on at

    A 502 can be caused by an overload. If you are running an older version or did not enable the prioritized based throttling in an environment before 10.0.19, then this could be indeed the same issue. When you enable the prioritized based throttling, instead of overloads, there will be an error 429 thrown which could be mitigated with a retry option.

  • D365FO user Profile Picture
    465 on at

    Hi Andre,

    How to check if throttling is enabled to see if i'll start getting 429 instead of 502?

    You mean i should fill the form in system administration? 

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

#2
André Arnaud de Calavon Profile Picture

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

#3
Sohaib Cheema Profile Picture

Sohaib Cheema 303 User Group Leader

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans