Lazarus

Programming => Operating Systems => Android => Topic started by: CC on June 30, 2019, 08:08:52 pm

Title: LAMW - ungraceful exit
Post by: CC on June 30, 2019, 08:08:52 pm
Hi,

A LAMW application exits without a beep  in a situation like this:

Code: Pascal  [Select][+][-]
  1.   aComponent:= nil;
  2.   aComponent.Tag:=1;
  3.  


An android  application built with Delphi at least displays an access violation message. Maybe there is something to learn from Delphi here. Maybe the difference  is in the Java part ...

An other related issue is that none of them actually executes the exception handling part of a try ..... except block in such a case. This makes proper exception handling impossible.

These problems are so fundamental. Unhandled exceptions  can cause terrible user experience and lots  of bad user reviews.
Title: Re: LAMW - ungraceful exit
Post by: jmpessoa on June 30, 2019, 09:45:42 pm

There is a workaround here:

"AppPascalLibExceptionHandlerDemo1"
Title: Re: LAMW - ungraceful exit
Post by: CC on July 01, 2019, 11:11:07 am
jmpessoa,

thanks for the tip, but unfortunately this does nor work for my original problem above (referencing a null pointer);
Title: Re: LAMW - ungraceful exit
Post by: CC on July 01, 2019, 11:27:55 am
Wow, I assumed not handling the null pointer exception was an FPC/DELPHI issue, but it  turns out it is deeper than that:

https://howtodoinjava.com/java/exception-handling/how-to-effectively-handle-nullpointerexception-in-java/ (https://howtodoinjava.com/java/exception-handling/how-to-effectively-handle-nullpointerexception-in-java/)
Title: Re: LAMW - ungraceful exit
Post by: CC on July 01, 2019, 11:37:51 am
So it basically says that  we need to check for null manually all the time.  The main point is to be able to catch the exceptions the developers missed in a graceful manner. What I would see as an accaptable solution is  to have  application level  exception handling for all the exceptions not dealt with so it could report a stacktrace to the developer and display a user friendly message to the user.

Maybe something like  this can be the solution:

Code: Java  [Select][+][-]
  1. public class BaseActivity extends Activity {
  2.     @Override
  3.     public void onCreate() {
  4.         super.onCreate();
  5.  
  6.         final Thread.UncaughtExceptionHandler oldHandler =
  7.             Thread.getDefaultUncaughtExceptionHandler();
  8.  
  9.         Thread.setDefaultUncaughtExceptionHandler(
  10.             new Thread.UncaughtExceptionHandler() {
  11.                 @Override
  12.                 public void uncaughtException(
  13.                     Thread paramThread,
  14.                     Throwable paramThrowable
  15.                 ) {
  16.                     //Do your own error handling here
  17.  
  18.                     if (oldHandler != null)
  19.                         oldHandler.uncaughtException(
  20.                             paramThread,
  21.                             paramThrowable
  22.                         ); //Delegates to Android's error handling
  23.                     else
  24.                         System.exit(2); //Prevents the service/app from freezing
  25.                 }
  26.             });
  27.     }
  28. }
Title: Re: LAMW - ungraceful exit
Post by: CC on July 01, 2019, 12:14:01 pm
I will think this through, just thinking loudly here:

Something like https://github.com/ACRA/acra (https://github.com/ACRA/acra) can be one way to  go,  or something like this:

Code: Java  [Select][+][-]
  1. public class CustomExceptionHandler implements UncaughtExceptionHandler {
  2.  
  3.     private UncaughtExceptionHandler defaultUEH;
  4.  
  5.     private String localPath;
  6.  
  7.     private String url;
  8.  
  9.     /*
  10.      * if any of the parameters is null, the respective functionality
  11.      * will not be used
  12.      */
  13.     public CustomExceptionHandler(String localPath, String url) {
  14.         this.localPath = localPath;
  15.         this.url = url;
  16.         this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
  17.     }
  18.  
  19.     public void uncaughtException(Thread t, Throwable e) {
  20.         String timestamp = TimestampFormatter.getInstance().getTimestamp();
  21.         final Writer result = new StringWriter();
  22.         final PrintWriter printWriter = new PrintWriter(result);
  23.         e.printStackTrace(printWriter);
  24.         String stacktrace = result.toString();
  25.         printWriter.close();
  26.         String filename = timestamp + ".stacktrace";
  27.  
  28.         if (localPath != null) {
  29.             writeToFile(stacktrace, filename);
  30.         }
  31.         if (url != null) {
  32.             sendToServer(stacktrace, filename);
  33.         }
  34.  
  35.         defaultUEH.uncaughtException(t, e);
  36.     }
  37.  
  38.     private void writeToFile(String stacktrace, String filename) {
  39.         try {
  40.             BufferedWriter bos = new BufferedWriter(new FileWriter(
  41.                     localPath + "/" + filename));
  42.             bos.write(stacktrace);
  43.             bos.flush();
  44.             bos.close();
  45.         } catch (Exception e) {
  46.             e.printStackTrace();
  47.         }
  48.     }
  49.  
  50.     private void sendToServer(String stacktrace, String filename) {
  51.         DefaultHttpClient httpClient = new DefaultHttpClient();
  52.         HttpPost httpPost = new HttpPost(url);
  53.         List<NameValuePair> nvps = new ArrayList<NameValuePair>();
  54.         nvps.add(new BasicNameValuePair("filename", filename));
  55.         nvps.add(new BasicNameValuePair("stacktrace", stacktrace));
  56.         try {
  57.             httpPost.setEntity(
  58.                     new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
  59.             httpClient.execute(httpPost);
  60.         } catch (IOException e) {
  61.             e.printStackTrace();
  62.         }
  63.     }
  64. }
  65.  
TinyPortal © 2005-2018