Retry after catch - java

Here's the logic I used:
int retries = config.get("retries");
Response resp = null
do {
try {
resp = operation.execute();
retries = 0;
} catch (Exception ex) { //Note. Please excuse this catch pattern. Its not a problem now.
if isAParticularException(ex) { //call a method to check the wrapped exception and other details
retries--;
LOGGER.info("Integrity exception, can be retried");
if (retries == 0) {
LOGGER.info("Retry exhausted");
throw ex;
}
LOGGER.info("Retrying operation, retry count " + ledgerRetry);
} else {
throw ex;
}
}
} while (retries > 0);
return resp;
Number of retries is considering original operation as well. But the problem is that
if I return from try block directly without assigning anything, then SCA (Fortify for me) reports that the variable retries is not read (in success flow), and
if I assign and do as above, then SCA shouts about the immediate
reassignment of value to the retries variable without even reading
it.
Considerations:
The first call should be independent of whatever value we read for
'retries'
Duplicate code should be avoided, and avoiding recursion will be
nice too.
May be a simple thing, but I am not catching it probably. Please suggest.

Why do you not use break instead of set retries to 0? I guess you sets retries after operation execute, because you want to break executing loop:
int retries = config.get("retries");
Response resp = null
do {
try {
resp = operation.execute();
break;
} catch (Exception ex) {
if isAParticularException(ex) { //call a method to check the wrapped exception and other details
retries--;
LOGGER.info("Integrity exception, can be retried");
if (retries == 0) {
LOGGER.info("Retry exhausted");
throw ex;
}
LOGGER.info("Retrying operation, retry count " + ledgerRetry);
} else {
throw ex;
}
}
} while (retries > 0);
return resp;
Or if you want you can return resp in try catch, and return null if did not execute anything:
int retries = config.get("retries");
Response resp = null
do {
try {
resp = operation.execute();
return resp;
} catch (Exception ex) {
if isAParticularException(ex) { //call a method to check the wrapped exception and other details
retries--;
LOGGER.info("Integrity exception, can be retried");
if (retries == 0) {
LOGGER.info("Retry exhausted");
throw ex;
}
LOGGER.info("Retrying operation, retry count " + ledgerRetry);
} else {
throw ex;
}
}
} while (retries > 0);
return null;
If I were you, I would consider throw exception instead of returning null.

Related

Koshuke Github api 403 forbidden after certain time

I have around 20 githubs that I update some information for with the koshuke GitHub API:
try {
settings = settingsRepository.findById(1).orElseThrow(() -> new RuntimeException("No settings found"));
GitHub gitHub = GitHub.connect(settings.getUsername(), settings.getToken());
GHRepository repo;
try {
repo = gitHub.getRepository(gitHubModel.getUser() + "/" + gitHubModel.getRepo());
} catch (Exception e) {
e.printStackTrace();
throw new GitHubRepositoryException("Couldn't connect to " + gitHubModel.getLink() + ". Check URL.");
}
There is event that loops around them on every 2-3 seconds, takes one of the githubs, updates it and after 2-3 seconds continues to the next one. After certain amount of updates the code stops at:
repo = gitHub.getRepository(gitHubModel.getUser() + "/" + gitHubModel.getRepo());.
I tried debugging and found out that it stops at certain point and it throws 403 Forbidden:
private <T> T parse(Class<T> type, T instance, int timeouts) throws IOException {
InputStreamReader r = null;
int responseCode = -1;
String responseMessage = null;
try {
responseCode = uc.getResponseCode();
responseMessage = uc.getResponseMessage();
if (responseCode == 304) {
return null; // special case handling for 304 unmodified, as the content will be ""
}
if (responseCode == 204 && type!=null && type.isArray()) {
// no content
return type.cast(Array.newInstance(type.getComponentType(),0));
}
r = new InputStreamReader(wrapStream(uc.getInputStream()), "UTF-8");
String data = IOUtils.toString(r);
if (type!=null)
try {
return setResponseHeaders(MAPPER.readValue(data, type));
} catch (JsonMappingException e) {
throw (IOException)new IOException("Failed to deserialize " +data).initCause(e);
}
if (instance!=null) {
return setResponseHeaders(MAPPER.readerForUpdating(instance).<T>readValue(data));
}
return null;
} catch (FileNotFoundException e) {
// java.net.URLConnection handles 404 exception has FileNotFoundException, don't wrap exception in HttpException
// to preserve backward compatibility
throw e;
} catch (IOException e) {
if (e instanceof SocketTimeoutException && timeouts > 0) {
LOGGER.log(INFO, "timed out accessing " + uc.getURL() + "; will try " + timeouts + " more time(s)", e);
return parse(type, instance, timeouts - 1);
}
throw new HttpException(responseCode, responseMessage, uc.getURL(), e);
} finally {
IOUtils.closeQuietly(r);
}
}
Then the exception is consumed and it comes to a point where it calls Thread.sleep and stops there.
Is this because I have exceeded the limit of requests? Somewhere I have read that it is 5000 request a minute and I am not doing that many. Any ideas why is this happening?

Try and Catch on an int Array not working as expceted

I am trying to perform try and catch on a method parameter but I not able to do it and when the program is ran it gives me the error number format error instead of executing the code in catch block
Any help is appreciated. I am a beginner to java and programming. Thank you for taking the time to read my question.
public void inputCheck(int[] checkUserInput) {
try {
if (!(checkUserInput[1] <= 10 && checkUserInput[1] % 2 == 0)) {
errorMessage = "failEven";
} else if (checkUserInput[0] < 20 || checkUserInput[0] > 80) {
errorMessage = "failRange";
} else if ((checkUserInput[0] >= 20 || checkUserInput[0] <= 80)
&& (checkUserInput[1] <= 10 && checkUserInput[1] % 2 == 0)) {
errorMessage = "checkpassed";
}
} catch (NumberFormatException e){
System.out.println("Please enter an number");
}
}
Error message
Exception in thread "main" java.lang.NumberFormatException: For input string: "e"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at UserInput.promptUser(UserInput.java:27)
at MainClass.main(MainClass.java:11)
#
Your code doesn't throw any type of exception so catch block is not executed at all.
In simple terms, your code in try block is free from any type of run time error so your catch block is not reached at all. Catch block is only executed when your code in try block throws a exception.
The catch block handling a certain type of an exception is executed only when the code in a try block produces an exception of this type. Thus, your code in a catch could be executed only if the code in a try block throws NumberFormatException, but it doesn't. You have to either explicitly throw such an exception in a try block or call a method that could throw it.
try {
if (someCondition) {
throw new NumberFormatException();
}
} catch (NumberFormatException exp) {
System.out.println("Invalid format" + e.getMessage());
}
There is no need for the try and catch block here. Also the parameter is array of int, you cannot pass string for the parameter.
You can make use of the below, the second ASCII value will be consider.
int arr[] = {100,'e'};

retry on some exceptions recursive

I have a method which uses proxies to retrieve information from a server. Sometimes due to a bad proxy I get SocketException, SSLException, SSLHandshakeException or ConnectException
I want the method to retry on the exceptions above, but on the IOException or no exception I want a string returned
Here is the method I constructed to test different scenarios
public String getTest(int i, int current, int total)
{
String text = "";
try
{
if (i == 1)
throw new IOException();
else if (i == 2)
throw new SSLException("SSLEx");
else if (i == 3)
throw new SocketException();
else
text = "EVERYTHING GOOD";
}
catch (SSLException | SocketException re)
{
if (current < total)
{
System.out.println("Recalling " + current);
getTest(1, ++current, total);
}
}
catch (IOException ioe)
{
text = "HTTP ERROR";
}
catch (Exception e)
{
e.printStackTrace();
}
return text;
}
I call my test method by
System.out.println(c.getTest(3, 0, 5));
Initially the program would catch a SocketException then retry by passing 1 so I can emulate a working proxy but a server response with IOException as i = 1 but the method never returns the text "HTTP ERROR"
What do I need to change in order for this to work as expected?
In order to return the string returned by your recursive function call, you must place return before the recursive function call like so...
return getTest(1, ++current, total);
Right now you are simply running the recursive function and discarding its return value. Your logic then returns your text string from the initial call (which in the case of an SSLException looks like an empty string).
You could also accomplish the same effect by assigning text from the recursive function...
text = getTest(1, ++current, total);
Both statements, considering the rest of your logic, are equivalent.

Is is dangerous to have a return statement in the finally clause in java? [duplicate]

This question already has answers here:
Returning from a finally block in Java
(6 answers)
Closed 7 years ago.
Look at the code below. Although the catch clause itself throws an exception, the finally block's return statement causes that exception to be swallowed. This method will return 420 even if something goes wrong in the catch block.
private static int foo() throws Exception
{
try {
throw new Exception("try");
} catch (Exception ex) {
throw new Exception("catch");
} finally {
String s = "";
return 420;
}
}
You should return something else if you encounters an Exception. The exception is only dangerous if the variable that threw that exception is used in the final return statement. Consider this:
int a;
try{
//...
}catch(Exception e){
//a throws an exception somehow
}finally{
returns a;
}
And when you use a on the other side like this:
a += 1;
You get a dangerous exception.
My suggestion is to do this:
try{
//...
}catch(Exception e){
//a throws an exception somehow
returns -1;
}finally{
returns a;
}
And on the other side:
if(return_value == -1) // skip or do something else;
This way, you won't get a unpredicted exception on the other side.
Return in finally is a very bad idea. It doesn't hide only the exceptions you throw yourself, but also virtual machine errors such as stack overflow or out of memory errors. These errors can be thrown at any point, including when the key invariants of data structures don't hold, and it will be impossible to predict what the program will do.
In your case it is safe, but if we change your scenario a little
private static FileReader foo() throws Exception{
try {
throw new Exception("try");
} catch (Exception ex) {
throw new Exception("catch");
} finally {
return new FileReader("");//this may also throw something
}
}
Now, because we didn't specify proper path in your file system return new FileReader(""); will throw FileNotFoundException and we will lose exception thrown in catch section with new Exception("catch"); which is potentially dangerous.

JAVA SSLENGINE: Unsupported record version Unknown-0.0 while trying to unwrap bytebuffer record with SSLEngine

I am using an SSLEngine over Java NIO unblocking server sockets to handle connections. I am able to successfully handshake the clients and pass small record sets to the server. However when I try to transfer a file to the server text/binary I am getting the following error:
javax.net.ssl.SSLException: Unsupported record version Unknown-0.0
at sun.security.ssl.InputRecord.checkRecordVersion(InputRecord.java:552)
at sun.security.ssl.EngineInputRecord.bytesInCompletePacket(EngineInputRecord.java:113)
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:862)
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:775)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
at ncp.io.network.tls.TLSWrapper.unwrap(TLSWrapper.java:170)
at ncp.io.network.tls.TLSIO.decodeData(TLSIO.java:110)
at ncp.io.network.tls.TLSIO.handleRead(TLSIO.java:71)
at ncp.io.network.SocketThread.run(SocketThread.java:137)
I am however unable to find out the reason for this error.
Below is my code snippet
#Override
public int handleRead(ByteBuffer temp) {
int read = opsManager.handleRead(temp);
if (read > 0) {
try {
tlsDecodeBuffer = decodeData(temp);
try {
temp.clear();
temp.put(tlsDecodeBuffer);
}catch (BufferOverflowException e){
temp = ByteBuffer.allocateDirect(tlsDecodeBuffer.remaining());
temp.put(tlsDecodeBuffer);
}
temp.flip();
temp.rewind();
if(tlsDecodeBuffer.hasRemaining())
tlsDecodeBuffer.compact();
else
tlsDecodeBuffer.clear();
}catch (SSLException e){
// Error occurs here:
e.printStackTrace();
log.warning("Insecure connection attempted/ SSL failure for:" + e.getMessage());
opsManager.close();
}
catch (IOException e) {
e.printStackTrace();
}
return read;
} else {
return -1;
}
}
private ByteBuffer decodeData(ByteBuffer input) throws IOException {
ncp.io.network.tls.TLSStatus stat = null;
boolean continueLoop = true;
do {
tlsDecodeBuffer = wrapper.unwrap(input, tlsDecodeBuffer);
switch (wrapper.getStatus()) {
case NEED_WRITE:
writeBuff(ByteBuffer.allocate(0));
break;
case UNDERFLOW:
if (tlsDecodeBuffer.capacity() == tlsDecodeBuffer.remaining()) {
throw new BufferUnderflowException();
} else {
input.compact();
continueLoop = false;
}
break;
case CLOSED:
if (log.isLoggable(Level.FINER)) {
log.finer("TLS Socket closed..." + toString());
}
throw new EOFException("Socket has been closed.");
default:
break;
}
stat = wrapper.getStatus();
} while (continueLoop && ((stat == TLSStatus.NEED_READ) || (stat == TLSStatus.OK))
&& input.hasRemaining());
if (continueLoop) {
if (input.hasRemaining()) {
input.rewind();
} else {
input.clear();
}
}
tlsDecodeBuffer.flip();
return tlsDecodeBuffer;
}
Your code doesn't make sense.
When you get a BufferOverflowException in unwrap(), you need to empty the target buffer via flip()/get()/compact().
When you get a BufferOverflowException in wrap(), you need to empty the target buffer via flip()/write()/compact(), where the write() goes to the network.
In neither case does it make any sense to allocate a new buffer etc.
rewind() after flip() doesn't begin to make sense in any context.
There are numerous posts and answers here about how to use the SSLEngine properly. I suggest you read them thoroughly.

Categories