I've just started to write an application.
I want to create a custom Exception class that spans over my whole application.
Want to do this so that every exception can be passed to that class file & whenever a exception is occurred, the Logs can be stored in one place.
I tired using this, but it does not seems an entirely good practice.
What is the best method to achieve this
Thank You
You could try just making a general (non-Exception) class, and pass the exception to it. Something like this should work:
Public Class ExceptionHandler {
public ExceptionHandler() {
}
public static handle(Exception e) {
// do stuff
}
}
in your code:
try {
}
catch(Exception e) {
ExceptionHandler.handle(e);
}
Related
I'm trying to create a custom Debug Tree class to get the same result as the following:
I have followed this Stackoverflow answer:
Log method name and line number in Timber
But using that answer gives me two problems:
Implementing the custom Debug Tree class does not log anything when I use more than one method.
public class MyDebugTree extends Timber.DebugTree {
#Override
protected String createStackElementTag(StackTraceElement element) {
return String.format("(%s:%s)#%s",
element.getFileName(),
element.getLineNumber(),
element.getMethodName());
}
}
public class BaseApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
Timber.plant(new MyDebugTree);
}
}
}
The above causes it to not log at all.
If I use only return element.getFileName(); it successfully logs that one error.
The second problem I'm having is that using a custom DebugTree class does not give me the same results as using err.getStackTrace()[0].getLineNumber().
}, err -> {
Timber.e("Method name: " + err);
Timber.e("Method name: " + err.getStackTrace()[0].getMethodName());
}
The custom Debug Tree class does not display the name of the method I'm trying to log.
Why is it not logging when I use all three methods?
Also how can I get it to log like it would using
err.getStackTrace()[0].getMethodName()?
I'm using 'com.jakewharton.timber:timber:4.7.1'
You seem to be doing it right. I recreated your code in kotlin (programming language should not matter) and i was able to show my logs.
MyDebugTree.kt
class QueenlyDebugTree : Timber.DebugTree() {
override fun createStackElementTag(element: StackTraceElement): String {
return "(${element.fileName}:${element.lineNumber})#${element.methodName}"
}
}
force log using an actual exception:
try {
throw RuntimeException("Hello World")
} catch (e: Exception) {
Timber.e(e)
}
i got a log:
So, from what i saw from your code, its most probably because you have a compact logcat view. To update your logcat view, follow these steps:
1. Make sure you have standard view selected
2. Configure standard view
3. Make sure Show tags is selected and tag column is at max(35)
I have a ReaderActivity.java class from where I call signString in signData.java class. If all is well then a new activity named ProductActivity is created. If there is exception in signString method, then ProductActivity is not supposed to be created.
The issue is, I still see ProductActivity is created even though I see the KSIEXCEPTION message in the log. What am I missing here?
public class ReaderActivity extends AppCompatActivity {
.....
public void setGlobal(String actualData) {
signData sign = new signData();
try {
sign.signString(getBaseContext(), finalResults, countToSend, locToSend, typeToSend);
Intent productIntent = new Intent(getBaseContext(), ProductActivity.class);
startActivity(productIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Now in the signData class I have the method
public class signData extends Activity{
public void signString(Context context, String data, String count, String loc, String type){
try {
/*some http connection code here*/
/*some computation related to specific API*/
}
catch (KSIException e) {
Log.i("KSIEXCEPTION","here");
e.printStackTrace();
}
}
}
You cant create object for an activity like this. signData sign = new signData();
2.
The issue is, I still see ProductActivity is created even though I see
the KSIEXCEPTION message in the log. What am I missing here?
Yes you just catching the exception in signString method, so after execution of this method definitely, it will create next activity.
If you dont want to go to next activity, you can move that method to some utility class and you can get some return value(boolean at-least) and based on that you can move to next activity
I have a utility method inside Utility.class which is a wrapper for sending Crashlytics events.
public static void logCrashlyticsEvent(String message) {
...
Crashlytics.getInstance().core.logException(new Exception(message));
...
}
The issue is whenever I use it from another class the Crashlytics dashboard shows the source for the event as Utility.class like this:
Utility.java line 106
com.myApp.util.Utility.logCrashlyticsEvent
Instead of the showing the it as the actual class who called it.
Is there a way wrap the call to Crashlytics so it will still show the calling class as the source for the event?
Thanks.
Edit:
Just to improve on #Andre Classen solution.
public static void logCrashlyticsEvent(HandledException e) {
Crashlytics.getInstance().core.logException(e);
Timber.e("Message: %s", e.getMessage());
// More stuff
}
HandledException:
public class HandledException extends Exception {
public HandledException(#NonNull String message, Object... args) {
super(String.format(message, args));
}
}
Usage:
Utility.logCrashlyticsEvent(new HandledException("Cast exception, input value1: %s, value2: %s", someValue, anotherValue));
You are creating a new Exception instead of logging the source exception , so the solution is easy:
public static void logCrashlyticsEvent(Exception e) {
.
.
Crashlytics.getInstance().core.logException(e);
.
.
}
To use it:
try{
String s=null;
int size=toString().length();
}
catch (NullPointerException e){
com.myApp.util.Utility.logCrashlyticsEvent(e);
}
This way the exception is logged the way you want it.
I am working on android library where I need to pass an exception object to a function. The function should cope with all Exception types and be able to return all of the available data within the exception, such as error message, stacktrace and inner exception.
Below is how I am passing the exception variable to my function within the catch statement.
try
{
txtText = (EditText)findViewById(R.id.txtTestEdit);
String test = txtText.getText().toString();
}
catch (NullPointerException ex)
{
CrashReporter.ReportCrash(ex);
}
Below is my function that needs to extract the exception type.
public static void ReportCrash(Object exceptionObject)
{
String exceptionType = exceptionObject.getClass().getName();
Log.d("Exception Type", exceptionType);
}
In this example the exception type is java.lang.NullPointerException. Is there a way I can return the Object called exceptionObject to the original exception to extract the stacktrace inner exception and error message.
Please note, this function should cope with all exception types not just a NullPointerException
Thanks for any help you can provide
The best way to do what you want is to use a callback, so that each method can handle it properly, but, if there is no callback then have it do some default behavior.
This way you can use properties in the method that had the error.
This question goes into more about callbacks in Android:
How to Define Callbacks in Android?
But, basically you create an interface that is implemented in a similar fashion as this:
CrashReporter.ReportCrash(ex, new ExceptionCallback() {
public void myExceptionCallback(Exception e) {
}
});
This code won't compile, but is just to show a possible way to implement it.
If your class has one callback that is needed, then you can create the callback listener earlier, and just pass it to the ReportCrash method.
I'm trying to call a function present in one class from another class by creating its object. Somehow it's not working. The new activity doesn't load.
My java code:
public class MessagesActivity extends TabActivity {
public WorkEntryScreenActivity workEntryObject = new WorkEntryScreenActivity() ;
public void AddWorkEntryClick(View v) {
workEntryObject.newWorkEntry();
}
}
The other class:
public class WorkEntryScreenActivity extends Activity {
public void newWorkEntry() {
try {
Intent i = new Intent(this, WorkEntryActivity.class);
i.putExtra("CurDate", mDateDisplay.getText());
i.putExtra("DD", String.valueOf(mDay));
i.putExtra("MM", String.valueOf(mMonth));
i.putExtra("YYYY", String.valueOf(mYear));
startActivity(i);
finish();
} catch (Exception e) {
System.out.println("Exception" + e.getStackTrace());
Log.d(TAG, "Exception" + e.getStackTrace());
}
}
}
You must create your workEntryObject first (it's not C++). Like this
public WorkEntryScreenActivity workEntryObject=new WorkEntryScreenActivity();
Also, I highly recommed you to read Android Basics
http://developer.android.com/guide/index.html
#biovamp is correct. It looks like you have a null reference that you're trying to call a method on. In order to call a non-static method, you need a instance of that object.
From the naming of your method, it looks like you might be trying to re-use some of your UI in another part of your application. In Android, the way to accomplish that is through Intents and Activities. If you're not familiar with those or how to use them, I would highly suggest researching them.