I want to know how to prevent the android application from crushing while an execution error happens.
I'm using this project here.
the error occurs when the requests does not find any result or when it takes to much time.
FetchExpression fetchExpression = new FetchExpression(
Utils.getEscapedContactSearchTermFetch(query));
mOrgService.RetrieveMultiple(fetchExpression, new Callback<EntityCollection>() {
#Override
public void success(EntityCollection entityCollection) {
mMainList.setAdapter(new SearchResultsAdapter(getApplicationContext(), entityCollection));
mSwipeRefresh.setRefreshing(false);
}
#Override
public void failure(Throwable error) {
displayError(error.getMessage());
}
});
the method failure does not work in some cases.
How can I prevent this application from crushing.
Thanks,
You should put that block of code in a try catch block and add the error you want to get in the catch block.
try {
some code here
....
} catch(Exception yourException) {
}
Related
I have a an application which has a kafka consumer and updates Elastic search according to the data it receives.
My issue is that when ever ES goes down, the kafka consumer stops completely and doesn't restart.
I believe its due to how my ES code is running:
public CompletionStage<SearchResponse> executeSearch(SearchRequest searchRequest) {
CompletableFuture<SearchResponse> f = new CompletableFuture<>();
client.searchAsync(searchRequest, RequestOptions.DEFAULT, new ActionListener<SearchResponse>() {
#Override
public void onResponse(SearchResponse searchResponse) {
f.complete(searchResponse);
}
#Override
public void onFailure(Exception e) {
throw new Exception(); // I am guessing because of this
}
});
return f;
}
If I change my onFailure method to:
public void onFailure(Exception e) {
f.complete(null);
}
It works perfectly but I dont understand why throwing an exception leads to this.
Any help would be greatly appreciated.
For those that need a solution, I changed my code to below for it to work with exception:
public void onFailure(Exception e) {
f.completeExceptionally(new Exception());
}
Also potentially relevant are the exceptionally method and the handle method from CompletableFuture
CompletableFuture.exceptionally((ex)-> ) - https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#exceptionally-java.util.function.Function-
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#handle-java.util.function.BiFunction-
When Tomcat session times out, I want to redirect my user to the homepage of my GWT app, so that they can login again. To force this, I'm trying to use the StatusCodeException thrown by GWT when the user tries to perform any operation after their session times out -
SEVERE: com.google.gwt.user.client.rpc.StatusCodeException: 0
To achieve this, I'm using the following code -
public void onModuleLoad() {
GWT.UncaughtExceptionHandler uncaughtExceptionHandler = new GWT.UncaughtExceptionHandler() {
public void onUncaughtException(Throwable e) {
if (e instanceof StatusCodeException) {
logger.log(Level.ERROR, "Exception caught!");
logger.log(Level.ERROR, ((StatusCodeException) e).getStatusCode());
}
}
};
GWT.setUncaughtExceptionHandler(uncaughtExceptionHandler);
try {
// rest of the code in onModule() - I'm expecting any operation to throw StatusCodeException when session times out.
} catch (RuntimeException ex) {
uncaughtExceptionHandler.onUncaughtException(ex);
}
}
This is not working. Instead of getting caught by the code, the StatusCodeException is being displayed on the console. What am I doing wrong here?
The idea is to catch StatusCodeException and use its getStatusCode() method to find out if the HTTP error code is 403. If it is, I want to use Window.Location.assign("https://example.com/redirect"); to redirect them to a login page.
onFailure(Throwable caught) {
logger.error(caught);
}
Your AsyncCallback.onFailure is doing exactly what you asked it to do - it is logging the error, but not throwing it. Since it wasn't thrown, the uncaught exception handler doesn't handle it (it can't be not-caught, if it wasn't thrown... if that makes sense).
One option could be that you could populate the method with throw caught, but java won't like this. Instead, the easiest answer to your specific on is simply to pass it to the handler:
onFailure(Throwable caught) {
GWT.getUncaughtExceptionHandler().onUncaughtException(ex);
}
One other option you have: since no AsyncCallback will ever throw this, putting the StatusCodeException in the UncaughtExceptionHandler seems a bit odd. Instead, consider making your own AsyncCallback base class, something like this:
public abstract class NetworkAsyncCallback<T> implements AsyncCallback<T> {
#Override
public void onFailure(Throwable t) {
if (e instanceof StatusCodeException) {
logger.log(Level.ERROR, "Exception caught!");
logger.log(Level.ERROR, ((StatusCodeException) e).getStatusCode());
}
}
}
Now, when you make a call, you just have to pass in a new NetworkAsyncCallback<T> and only implement onSuccess. You can skip onFailure if all it was going to do was pass the exceptions to the uncaught handler. Or, if you have some other logic, you can override onFailure, handle the appropriate exceptions, and call super.onFailure(caught) with any other errors so that the superclass handles it.
myServer.getSomeData(param, new NetworkAsyncCallback<Result>() {
#Override
public void onSuccess(Result result) {
//...
}
// Skip onFailure, or if you need custom logic, implement it,
// and call super only if the exception isn't part of that logic
});
I have created a small example of reading a text file and wrap the call with CompletableFuture.
public class Async {
public static void main(String[] args) throws Exception {
CompletableFuture<String> result = ReadFileUsingLambda(Paths.get("path/to/file"));
result.whenComplete((ok, ex) -> {
if (ex == null) {
System.out.println(ok);
} else {
ex.printStackTrace();
}
});
}
public static CompletableFuture<String> ReadFileUsingSupplier(Path file) throws Exception {
return CompletableFuture.supplyAsync(new Supplier<String>() {
#Override
public String get() {
try {
return new String(Files.readAllBytes(file));
} catch (IOException e) {
e.printStackTrace();
return "test";
}
}
}, ForkJoinPool.commonPool());
}
public static CompletableFuture<String> ReadFileUsingLambda(Path file) throws Exception {
return CompletableFuture.supplyAsync(() -> {
try {
return new String(Files.readAllBytes(file));
} catch (IOException e) {
e.printStackTrace();
return "test";
}
} , ForkJoinPool.commonPool());
}
}
This code returns nothing. It executes and "nothing happens", no errors or output. If I call ReadFileUsingSupplier instead of ReadFileUsingLambda then I get the file content printed in the console!
To me this doesn't make sense because a lambda is a shorthand for writing an inline function and it shouldn't change the behaviour but in this example it does apparently.
I think it's just a matter of execution timing - the lambda may take a little more to execute, allowing the program to exit before you are done reading the file.
Try this:
add a Thread.sleep(1000); as the first statement within the try block in ReadFileUsingSupplier and you won't see any output
add a Thread.sleep(1000); at the end of your main when using ReadFileUsingLambda and you will see the expected output
To make sure your main doesn't exit before the future is completed, you can call:
result.join();
As noted, you need to result.join() in either case to avoid the main thread exiting too quickly.
It seems that there's a penalty for using lambdas vs anonymous closures while the JVM warms up, thereafter the performance is the same. I found this information at on another SO thread - which in turn links a performance study by Oracle.
As a sidenote it's not a great idea to Thread.sleep() to fix weird timing issues, ever. Figuring out the cause and applying the appropriate measures would be much clearer when re-read by you or by others, e.g.
System.out.println(result.get(5, TimeUnit.SECONDS));
This enables you to ditch the .join(), too.
I'm using a crash report library in my Android project. Once activated, it reacts to every uncatched exception and creates a report just before the app shutdown.
So far so good, but I want to add more "control" to this thing and create reports for non-Exceptions too. My idea is to define a "fake" Exception this way:
public final class NonFatalError extends RuntimeException {
private static final long serialVersionUID = -6259026017799110412L;
public NonFatalError(String msg) {
super(msg);
}
}
So, when I want to send a non-fatal error message and create a report, I'll do this:
throw new NonFatalError("Warning! A strange thing happened. I report this to the server but I let you continue the job...");
If called from the main thread, this obviously makes the app crash. So, I tried to throw it on a background thread!
new Thread(new Runnable() {
#Override
public void run() {
throw new NotFatalError("Warning! A strange thing happened. I report this to the server but I let you continue the job...");
}
}).start();
A great idea? No. The app crashes anyway (but the fake crash report is sent as expected). Is there another way to achieve what I want?
Your exception never gets caught, so that's why your application is crashing.
You can do this do catch the exception from your main thread:
Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread th, Throwable ex) {
System.out.println("Uncaught exception: " + ex);
}
};
Thread t = new Thread(new Runnable() {
#Override
public void run() {
throw new NotFatalError("Warning! A strange thing happened. I report this to the server but I let you continue the job...");
}
});
t.setUncaughtExceptionHandler(h);
t.start();
But you can also run the code from your main thread and catch it there.. Like:
try
{
throw new NonFatalError("Warning! blablabla...");
}
catch(NonFatalError e)
{
System.out.println(e.getMessage());
}
Because your exception is extended from the RuntimeException class the default behaviour is to exit the application if the exception is not catched anywhere. So that's why you should catch it before the Java Runtime decides to quit the app.
You are using exception to create logs. You shouldnt do that. If you are using a library like crashlytics (https://try.crashlytics.com/) you can send log reports like in this link: http://support.crashlytics.com/knowledgebase/articles/120066-how-do-i-use-logging
The library you are using should have a similar method.
If you want to continue to use Exceptions, you need to catch them to not crash the application.
I want to override the global Exception Handling in my RCP app. Whenever an uncaught Exception happens I want to log it (using java logging) and then exit the app. I have already overwritten the eventLoopException(Throwable exception) method in the ApplicationWorkbenchAdvisor class. But this catches only the event loop exceptions. As of now I have also overwritten the postStartup() method like this:
public void postStartup()
{
Policy.setStatusHandler(new StatusHandler()
{
#Override
public void show(IStatus status, String title)
{
LOGGER.log(Level.SEVERE, "Uncaught Exception", status.getException());
UnexpectedErrorDialog();
PlatformUI.getWorkbench().close();
}
});
}
It logs the exception in my log file and exits the app. But it's obviously not right and the exception is shown twice in the console, cause all I do is intercepting the showing of the exception in a gui dialog to the user. So how can I properly overwrite/change the global exception handling, so that my code (log) is used instead of the default one?
I would suggest you to use org.eclipse.ui.statusHandlers extension point
Thanks to sambi reddy's tip i have now overwritten AbstractStatusHandler in the ApplicationWorkbenchAdvisor class
#Override
public synchronized AbstractStatusHandler getWorkbenchErrorHandler() {
if (myStatusHandler == null) {
myStatusHandler = new MyStatusHandler();
}
return myStatusHandler;
}
MyStatusHandler extends AbstractStatusHandler and i have overwritten the handle method like this:
#Override
public void handle(StatusAdapter statusAdapter, int style)
{
if(statusAdapter.getStatus().matches(IStatus.ERROR) && ((style != StatusManager.NONE)))
{
LOGGER.log(Level.SEVERE, "Uncaught Exception", statusAdapter.getStatus().getException());
UnexpectedErrorDialog();
PlatformUI.getWorkbench().close();
}
}
seems to work right, only downside is that i still get 2 console outputs.