How to retry at verification tab on api-objet?

Hello,
There are several API-REST request we use in our test.
We used them several times at hundred of differents tests cases.
Due to server instability, 1/1000 appr crashed with html error.
In prod those request have retry in those cases.
We want to relaunch only the request with the same parameter.

We’d like to reproduce this at OR request level, on verification tab (We want to avoid refactoring all).

RequestObject request = WSResponseManager.getInstance().getCurrentRequest()

ResponseObject response = WSResponseManager.getInstance().getCurrentResponse()

String contentType = response.getHeaderFields().get('Content-Type').get(0)

//Check if response is HTML
if(contentType.contains('text/html')) {
	//retry here
}

Here is an example

Of course we’ll ensure to do it 3 times max.

Thanks,

1 Like

Hi there,

Thank you very much for your topic. Please note that it may take a little while before a member of our community or from Katalon team responds to you.

Thanks!

No. I don’t think that the script coded in the Verification tab is capable to trigger an retry sending an HTTP request.

I would say, Katalon Studio offers no built-in feature of “retrying API Request”. You need to implement “retry” by your own code.

If you are willing, you can implement “retry”. For example, previously, there was a discussion originated by @mqamar, which looks quite similar to your case.

There I proposed an idea but @mqamar quit the discussion. Possibly @mqamar did not like my idea because it involved a lot of code changes for him. I am afraid, @geoffrey.doco might be disappointed as well.

1 Like

If @geoffrey.doco is willing to do a heavy refactoring, I have an idea to suggest to him.

Have a look at the source code of com.kms.katalon.core.webservice.keyword.builtin.SendRequestKeyword:

package com.kms.katalon.core.webservice.keyword.builtin

import com.kms.katalon.core.annotation.internal.Action
import com.kms.katalon.core.configuration.RunConfiguration
import com.kms.katalon.core.keyword.internal.KeywordMain
import com.kms.katalon.core.keyword.internal.SupportLevel
import com.kms.katalon.core.model.FailureHandling
import com.kms.katalon.core.testobject.RequestObject
import com.kms.katalon.core.testobject.ResponseObject
import com.kms.katalon.core.webservice.common.HarLogger
import com.kms.katalon.core.webservice.common.ServiceRequestFactory
import com.kms.katalon.core.webservice.constants.StringConstants
import com.kms.katalon.core.webservice.helper.WebServiceCommonHelper
import com.kms.katalon.core.webservice.keyword.internal.WebserviceAbstractKeyword
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject

import groovy.transform.CompileStatic

@Action(value = "sendRequest")
public class SendRequestKeyword extends WebserviceAbstractKeyword {

    @CompileStatic
    @Override
    public SupportLevel getSupportLevel(Object ...params) {
        return super.getSupportLevel(params)
    }

    @CompileStatic
    @Override
    public Object execute(Object ...params) {
        RequestObject request = (RequestObject) params[0]
        FailureHandling flowControl = (FailureHandling)(params.length > 1 && params[1] instanceof FailureHandling ? params[1] : RunConfiguration.getDefaultFailureHandling())
        return sendRequest(request,flowControl)
    }

    @CompileStatic
    public ResponseObject sendRequest(RequestObject request, FailureHandling flowControl) throws Exception {
            Object object = KeywordMain.runKeyword({
                WebServiceCommonHelper.checkRequestObject(request)
                ResponseObject responseObject = WebServiceCommonHelper.sendRequest(request)
                
                boolean enableHarFileGeneration = RunConfiguration.getHarFileGeneration();
                if(enableHarFileGeneration) {
                    HarLogger harLogger = new HarLogger()
                    harLogger.initHarFile()
                    harLogger.logHarFile(request, responseObject, RunConfiguration.getReportFolder())
                }
                
                logger.logPassed(StringConstants.KW_LOG_PASSED_SEND_REQUEST_SUCCESS)
                return responseObject
            }, flowControl, StringConstants.KW_LOG_FAILED_CANNOT_SEND_REQUEST)
            if (object instanceof ResponseObject) {
                return (ResponseObject) object
            }
            return null
    }
}

@geoffrey.doco can study this. He should be able to develop a new Custom Keyword, which inherites the built-in SendRequestKeywrod class while he want to add the “retry” processing the sendRequest method:

for (max N times) {
    WebServiceCommonHelper.checkRequestObject(request)
    ResponseObject responseObject = WebServiceCommonHelper.sendRequest(request)
    //Check if response is HTML
    String contentType = responseObject.getHeaderFields().get('Content-Type').get(0)
    if(!contentType.contains('text/html')) {
        break
    } else {
        // log error, wait a while and retry sending request
    }
}
...
return responseObject

Once @geoffrey.doco got his own Custom keyword “sendRequestWithRetry” keyword, he would want to edit his test cases to call “sendRequestWithRetry” instead of the built-in “sendRequest”.


To add more aggressive approach, Groovy’s Metaprogramming technique is applicable. Groovy allows you to rewrite sendRequest() method of com.kms.katalon.core.webservice.keyword.builting.SendRequestKeyword class dynamically at runtime. Once you could rewrite the implementation of the SendRequestKeyword#sendRequest() method so that it internally performs “retry when HTML is responded”, then @geoffrey.doco would be able to change the behavior of Test Cases just a bit of configurational code.

1 Like

By the way, where can we find the source code of the com.kms.katalon.core.* classes?

On my Mac installation, I can find the jar files of the source code in the following path

  • /Applications/Katalon Studio.app/Contents/Eclipse/configuration/resources/source

Windows users and Linux users should be able to find the similar path in their own Katalon Studio installation folder.

By the way, if you are using Katalon Studio v9.1 or newer version and you want to develop a Custom Keyword, you need to purchase an Enterprise license. The v9.0 and older versions, Custom Keyword remains available for the Free licensees.

PLS have a look at this:

2 Likes

Hey @geoffrey.doco,

Please take a look at those suggestions above and let us know if it works/does not work as the reference for others. Thank you :wink:

Thank you, we’re currently implementing the solution above with some adaptation. It look very promising.

2 Likes

Hi there Geoffrey, :wave:

Just checking in to see if the suggestions and workaround by kazurayam were able to help resolve your issues or not.

Thanks,
Albert

Hi folks @here, :wave:

As we have yet to see the OP of this thread (@geoffrey.doco) confirm whether or not the proposed solutions here work for him. We will assume that the issue has been solved and will proceed to close this thread up soon.

Thanks,
Albert

Hi, thank you, it currently works for us with very few adaptation. (closure condition, add it in prerequest tests listeners…)

My post Modifying WS.sendRequest keyword to support implicit retry on server error has got only 125 views. I am disappointed with this small number. Who really uses KS for API testing? Only @geoffrey.doco? Possibly.

This topic was automatically closed after 40 hours. New replies are no longer allowed.