Android Tutorial Uncaught Exceptions

Discussion in 'Tutorials & Examples' started by Erel, Oct 29, 2015.

  1. Erel

    Erel Administrator Staff Member Licensed User

    By default, when there is an uncaught exception the program will show a message box with the error title and the user will be asked whether they want to continue or not.

    There are several problems with this behavior:
    1. The user cannot really know whether the program can continue correctly after the uncaught exception.
    2. A crash report will not be sent to Google Play as the error was eventually caught internally.
    3. It is inconsistent as the dialog only appears when the error happens with an activity context.
    4. It was not possible to override this behavior and allow sending the error with an email for example.

    Starting from B4A v5.50 it is possible to change this behavior.
    If there is a sub named Application_Error in the Starter service module then the default error dialog will never appear.
    Note that the starter service template includes this sub. It is recommended to include this sub in all projects.

    Code:
    'Return true to allow the OS default exceptions handler to handle the uncaught exception.
    Sub Application_Error (Error As Exception, StackTrace As StringAs Boolean
       
    Return True
    End Sub
    If you return True from this sub then the OS default exceptions handler is called. The result is that the app will crash and the crash report will be sent to Google Play (if the user allows it).
    This is a good and standard behavior.

    If you return False then the default exceptions handler will not be called. This means that the app will continue to run.

    A proper usage of this is to allow you to use alternative methods to send the crash report. For example you can use HttpUtils2 to send the StackTrace to your server and then kill the process in the JobDone event.

    Notes

    - Application_Error will only be called in Release mode. In Debug mode the program will print the error message in the logs and will end.
    - Errors that happen when the app is started, before the Starter service is ready will not be trapped. The OS default exceptions handler will handle those errors.
    - The starter service must be running for this sub to be raised. It will be running unless you explicitly stop it.

    An example of catching the recent logs and sending them with an intent is attached.

     

    Attached Files:

    Last edited: Nov 4, 2015
  2. ArminKH

    ArminKH Well-Known Member

    Is this possible to use this sub directly in activity?i know maybe by callsub but maybe some apps don't need any starter service
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    No. It must be inside the Starter Service. There is no reason not to use the starter service.
     
    luke2012 and ArminKH like this.
  4. ArminKH

    ArminKH Well-Known Member

    Ok and also can u please add an extra variable for LineNumber separatly? Because i want to use this future insted try catch and i want to know which line is sent error message to that sub
    I know maybe line number can be accessable inside exception message but i want an extra and separate variable for that if is possible
    Yes but when my app has not any global resources or initializes starter service is necesaary?
     
    Last edited: Oct 29, 2015
  5. Erel

    Erel Administrator Staff Member Licensed User

    The line number is not known in release mode. Only the java line number (which is included in the stack trace).

    It is not necessary in that case but it will not do any harm.
     
    luke2012 and ArminKH like this.
  6. Informatix

    Informatix Expert Licensed User

    Erel could create a class for StackTrace elements. I had to create one in one of my libraries because it is really useful:
    Code:
    @BA.ShortName("ANRWatchDog_StackTraceElement")
        
    public class StackTraceElem
        {
            final 
    String ClassName, FileName, MethodName, toString;
            final int LineNumber;
            final boolean IsNative;

            StackTraceElem(StackTraceElement STE)
            {
                ClassName = STE.getClassName();
                MethodName = STE.getMethodName();
                FileName = STE.getFileName();
                LineNumber = STE.getLineNumber();
                IsNative = STE.isNativeMethod();
                toString = STE.toString();
            
    }

            public String getClassName()
            {
                return ClassName;
            }

            public String getFileName()
            {
                return FileName;
            }

            public boolean getIsNativeMethod()
            {
                return IsNative;
            }

            public int getLineNumber()
            {
                return LineNumber;
            }

            public String getMethodName()
            {
                return MethodName;
            }

            public String toString()
            {
                return toString;
            }
        }
     
  7. ArminKH

    ArminKH Well-Known Member

    Thank u, any way i'm so intrested,if this future added then try catch will be join to history :)
     
  8. Cableguy

    Cableguy Expert Licensed User

    Why??? Try/catch blocks are very useful to prevent an app from crashing due to an unset variable or disposed resource, while the feature here presented, as I understand it, will allow an app to proceed even if an (major) error is fired, thus giving the opportunity to the developers to get this error and try to act upon it.
     
    ArminKH likes this.
  9. ArminKH

    ArminKH Well-Known Member

    not sure,but as erel said : If there is a sub named Application_Error in the Starter service module then the default error dialog will never appear.
    as i understand by using this future and if LineNumber added then there is not need to use try catch longer,because all errors can be handled in 1 sub
     
  10. Informatix

    Informatix Expert Licensed User

    I don't understand how you can handle all application exceptions in an unique place. You need to know, for example, whether it's recoverable or not depending on the context. A stack trace does not help to decide whether the error can be ignored or not at runtime. Erel added this event for uncaught exceptions, not to handle all app exceptions.
     
  11. ArminKH

    ArminKH Well-Known Member

    yes you are right maybe i'm confused today ,anyway thank u both for explanation
     
    Informatix likes this.
  12. JakeBullet70

    JakeBullet70 Well-Known Member Licensed User

    Oh I need this!!! Thanks Erel!!!!
     
  13. JakeBullet70

    JakeBullet70 Well-Known Member Licensed User

    I know this might be too much but how about a method to get the Android logs for our own app?
     
  14. aaronk

    aaronk Well-Known Member Licensed User

    Just want to confirm..

    From what I understand, if my app comes up with a message box like:

    upload_2015-10-30_13-52-36.png

    It allows the user to press 'yes' or 'no'. If the user presses on 'yes' it will keep running the app. Pressing 'No' will close the app. Will the above code capture that error and allow me to send a email for example when this internal error happens so we know where this error happens (such as viewing the StackTrace for fault finding)?

    If so, this new feature is going to be good. Currently as you can see it doesn't tell you anything about that error and I need to just look though the whole app to find why this error come up. This error happens here and there with my app (so the customer says).

    Does this also work if the app crashes? Normally crash reports popup in Google Play but the customer would need to send it. Does this work when the app crashes or when a ANR happens or does the above code only work when a internal error happens?

    Also, if you use code like the following would that send the crash by email and also send it in Google Play etc since it's set to Return True ?

     
  15. Erel

    Erel Administrator Staff Member Licensed User

    This is already possible with LogCat from the Phone library.

    @aaronk if you add the Application_Error sub then this dialog will never appear.

    It will work with most app crashes. It will not work with ANRs.

    The problem with this code is that the process will be killed before the mail is sent.
    You need to wait for the MessageSent event. You will be able to call the OS default exceptions handler using JavaObject.
     
    JakeBullet70 likes this.
  16. Informatix

    Informatix Expert Licensed User

    Even OutOfMemory and StackOverflow errors ?
     
  17. Erel

    Erel Administrator Staff Member Licensed User

    Yes (as long as the VM itself doesn't crash).
     
    Peter Simpson likes this.
  18. Erel

    Erel Administrator Staff Member Licensed User

    An example was added to the first post. It demonstrates how to catch the logs and send them when the app crashes.
     
    Peter Simpson and cimperia like this.
  19. JakeBullet70

    JakeBullet70 Well-Known Member Licensed User

    Any idea when 5.5 will be available?
     
  20. Pendrush

    Pendrush Active Member Licensed User

Loading...