Android studio debbuger always step on last catch block even not exceptions - java

I have this class:
public class ConnectionInterceptor implements Interceptor {
#Override
public Response intercept(#NonNull Chain chain) throws IOException {
Request request = chain.request();
Response response;
try {
response = chain.proceed(request);
} catch (ConnectException e) {
throw new IOException("Ошибка соединения с сервером");
} catch (SocketTimeoutException e) {
throw new IOException("Время ожидания соединения истекло");
} catch (Exception e) {
System.out.println("error: " + e.getMessage());
throw new IOException(e.getMessage());
}
if (response.code() == 500) {
throw new ApiNfpException("Ошибка с кодом 500");
}
return response;
}
}
When I get success response (status 200) in debug mode, I see some strange behavior in Android Studio. The debugger stops on the last catch block.
Step 1: I have set many breakpoints. I send a request to server and get response. I stop on this line:
Step 2: I check the error:
Step 3: I press F9 button and move to next line:
If I remove the third catch block, I stop on the second block. Why does the debugger stop on the catch block if there is seemingly no error?

Related

Android crash report shows exception that is caught

I have an Android app written in Java, and recently noticed many crash reports occurring in an AsyncTask. The stack trace makes no sense, as it is inside a try/catch so there is no way for the exception to be thrown. How can a caught exception cause an app crash?
13: public class HttpGoogleSignInAction...
#Override
protected String doInBackground(Void... voids) {
try {
// Check if user exists
UserConfig user = null;
31: user = MainActivity.connection.fetch(this.config);
if (user == null) {
} else {
// User exists, try to sign in user
this.config = MainActivity.connection.connect(this.config);
}
} catch (Exception userDoesNotExist) {
try {
// User does not exist, try to create user
this.config = MainActivity.connection.create(this.config);
} catch (Exception exception) {
this.exception = exception;
}
}
return "";
}
public String POST(String url, String xml) {
if (this.debug) {
System.out.println("POST: " + url);
System.out.println("XML: " + xml);
}
String result = "";
try {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(url);
StringEntity content = new StringEntity(xml, "utf-8");
content.setContentType("application/xml");
httpPost.setEntity(content);
HttpResponse response = httpClient.execute(httpPost, localContext);
HttpEntity entity = response.getEntity();
if (entity != null) {
result = EntityUtils.toString(entity, HTTP.UTF_8);
}
if ((response.getStatusLine().getStatusCode() != 200) && (response.getStatusLine().getStatusCode() != 204)) {
this.exception = new SDKException(""
+ response.getStatusLine().getStatusCode()
+ " : " + result);
2205: throw this.exception;
}
} catch (Exception exception) {
if (this.debug) {
exception.printStackTrace();
}
this.exception = new SDKException(exception);
2213: throw this.exception;
}
return result;
}
The stack trace shows the crash occurring in the line,
user = MainActivity.connection.fetch(this.config);
It is a normal RuntimeException subclass exception being thrown, which should be caught. If I try to force an exception to test it the try/catch works fine and no crash, but in 1% of users using the app I am seeing crashes, others it works fine.
Makes no sense.
This is the stack trace from Google Play, SDKException is a subclass of RuntimeException, the line of code it occurs in is inside try/catch
org.botlibre.sdk.SDKException:
at org.botlibre.sdk.SDKConnection.POST (SDKConnection.java:2213)
at org.botlibre.sdk.SDKConnection.fetch (SDKConnection.java:259)
at ...HttpGoogleSignInAction.doInBackground (HttpGoogleSignInAction.java:31)
at ...HttpGoogleSignInAction.doInBackground (HttpGoogleSignInAction.java:13)
at android.os.AsyncTask$3.call (AsyncTask.java:394)
at java.util.concurrent.FutureTask.run (FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run (AsyncTask.java:305)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:641)
at java.lang.Thread.run (Thread.java:923)
Caused by: org.botlibre.sdk.SDKException:
at org.botlibre.sdk.SDKConnection.POST (SDKConnection.java:2205)
org.botlibre.sdk.SDKException:
at org.botlibre.sdk.SDKConnection.POST (SDKConnection.java:2213)
at org.botlibre.sdk.SDKConnection.fetch (SDKConnection.java:259)
Shows that you're throwing the exception captured here in doInBackground():
try {
// User does not exist, try to create user
this.config = MainActivity.connection.create(this.config);
} catch (Exception exception) {
**this.exception = exception;**
}
}
Even though this execption is within a catch block, since it's persisted and then thrown later it is now outside of a try-catch block and can crash the app. That is
try {
...
} catch (Exception exception) {
if (this.debug) {
exception.printStackTrace();
}
this.exception = new SDKException(exception);
// This line will throw an execption that will have the message from the original exception.
2213: throw this.exception;
}
The source for SDKException's single exception constructor shows it reuses the message from the exception parameter.
You are very clearly re-throwing the caught exception on line 2213. If you throw an exception from a catch block, it escapes the try/catch because you are throwing it from a scope of code that is not surrounded by try { }.
As for why fetch() might be throwing, we would have to see the code to be able to guess.
Even though you have your code wrapped in try catch, there is a possibility of a crash if different threads are involved. try catch does not catch exceptions from child threads, so if any of your methods(like .fetch or .connect) used in doInBackground are internally using/creating different threads and an exception is thrown within that thread it might cause the app to crash. Looking at the logs, it is possible the .fetch method is asynchronous and performing operations in a different thread.

Handle rest template errors

I developed a service, using resttemplate and using this service(clientproject) in another project(server), I am trying to throw the exception from resttemplate and handle at server project,but it is not working.
Here is my code:
public class UserService{
public long createUser(Long servcieId){
long userId =0L;
try
{
response = restTemplate.exchange(url,HttpMethod.POST, request, Object.class);
userId = response.getBody().getUser().getId();
}
catch(RestClientException e){
throw e;
}
return userId;
}
}
Here is my service code:
public Long createUserInPortal(Long serviceId){
try
{
Long userId=userService.createUser(serviceId);
}
catch(RestClientException e){
if(e instanceof HttpStatusCodeException){
String errorResponse=((HttpStatusCodeException)e).getResponseBodyAsString();
logger.error("the error in user service is:"+errorResponse);
}
}
I am getting the following error,"resulted in 422 (Unprocessable Entity); invoking error handler".
I am trying to see the response string in the catch block but it is not reaching this catch block.
well may be its getting inside catch block but gets filtered by
if(e instanceof HttpStatusCodeException){ condition
May be e instance is not of type HttpStatusCodeException there are other possibilities like
} catch (HttpClientErrorException e) {
success = false;
Log.e(TAG, command+" was rejected for URL: "+url, e);
resultCode = e.getStatusCode().value();
response = e.getResponseBodyAsString();
} catch (HttpServerErrorException e) {
success = false;
Log.e(TAG, command+" could not be completed for URL: "+url, e);
resultCode = e.getStatusCode().value();
response = e.getResponseBodyAsString();
} catch (ResourceAccessException e) {
if (attemptsLeft > 0) {
Log.w(TAG, command+" failed I/O, retrying.", e);
return simplePut(baseUrl, url, b, command, payload, attemptsLeft);
}
success = false;
Log.e(TAG, command+" failed I/O for URL: "+url, e);
resultCode = 499;
} catch (RestClientException e) {
success = false;
Log.e(TAG, command+" failed for URL: "+url, e);
resultCode = 599;
}

Best practice - Generic webdriverWait till loading popup exist, if error appears fail the test

My problem is I have customWaitMethods such as:
public void waitForLoading(WebElement loadingElement, WebElement errorElement) {
long timeOut = Long.parseLong(PropertyReader.getInstance().getProperty("DEFAULT_TIME_OUT"));
try {
WebDriverWait wait = new WebDriverWait(DriverFactory.getInstance().getDriver(), timeOut);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id(loadingElement.toString())));
if (errorElement.isDisplayed()) {
throw new TestException();
}
} catch (TimeoutException e) {
System.out.println("Timed out after default time out");
} catch (TestException e) {
System.out.println("Unexpected error occurred, environment error");
e.printStackTrace();
}
}
I need some generic customWait methods. I do a search, but several cases need to be handled. Error msg appear -> fail the test. wait for the loading content, and it disappeared, -> check the search result.
How can I extend this code if I would like to check continuously some error_message element appears as well and in this case I would throw an exception? So independently I can handle the timeout exception and the other, error msg?
This sript is failing because of the IF. ErrorElement does not appear on the page, ---> nosuchelementException
You can catch different Exceptions as you see fit. In your case, you want to catch the TimeoutException to handle time outs. Then catch a different type of exception to handle the error message:
public void waitForLoading() {
long timeOut = Long.parseLong(...);
try {
WebDriverWait wait = new WebDriverWait(...);
wait.until(ExpectedConditions.invisibilityOfElementLocated(...));
if (<error-message-appears>) {
throw new CustomErrorMessageAppearedException();
}
} catch (TimeoutException e) {
System.out.println("Timed out after...");
} catch (CustomErrorMessageAppearedException e) {
// handle error message
}
}
The easiest approach I see is:
public void waitForLoading() {
long timeOut = Long.parseLong(PropertyReader.getInstance().getProperty("DEFAULT_TIME_OUT"));
try {
WebDriverWait wait = new WebDriverWait(DriverFactory.getInstance().getDriver(), timeOut);
if (!wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("wait_element")));)
{
throw new NoSuchElementException();
}
} catch (TimeOutException e) {
System.out.println("Timed out after " + timeOut + "seconds waiting for loading the results.");
}
}

Java throw e becomes null on Android

I have the following:
try {
response.statusCode = urlConnection.getResponseCode();
} catch(IOException e) {
throw e;
}
I look at the debugger and e = UnknownHostException
After the throw I have:
try {
NetworkResponse response = NetworkHelper.getByURL(url);
} catch(Exception e) { <------- IT LANDS HERE, BUT e=null
ExceptionHelper.announce(e);
throw e;
}
So after the throw my catch block gets the exception but it's null.
The debugger shows e=null.
I have no idea why this would happen.
I don't even see the point of catching the exception if you just immediately rethrow it. Add a throws IOException to that method and let the other catch handle it.

I have a ConnectException that isn't being caught for some reason

I'm working on an Android application that uses sockets. I have a function called initializeStreams() which opens the socket and attempts a connection. This function throws a ConnectException if the connection could not be established. But for some reason, in the code that calls initializeStreams(), which has a catch block for ConnectException, the log prints out its own stack trace for the exception instead of going to the catch block. The catch block is never reached at all, even though the exact exception is being thrown. Here's the code:
The try block:
try {
initializeStreams();
/* other code */
} catch (ConnectException e) {
Log.i(TAG, "caught connect exception");
}
initializeStreams():
public void initializeStreams() throws ConnectException {
try {
Log.i(TAG, "Attempting to connect");
requestSocket = new Socket(SERVER_ADDR, PORT);
/* other code */
} catch (IOException e) {
e.printStackTrace();
}
I can't figure this out, so any help would be much appreciated.
You need to chain your Exception throwing it in the catch block. Try the following:
public void initializeStreams() throws ConnectException {
try {
Log.i(TAG, "Attempting to connect");
requestSocket = new Socket(SERVER_ADDR, PORT);
/* other code */
} catch(ConnectException e){
throw e;
}
catch (IOException e) {
e.printStackTrace();
}
ConnectException extends SocketException which in turn extends IOException, so the catch for IOException in initializeStreams() catches the ConnectException. I would just remove that try/catch block altogether: there's not much point in returning cleanly from this method without a connection.

Categories