How to call a function on processing crash?

I'm trying to write a function that would be called if my processing sketch has crashed. I managed to make it so that the function is called if the program is exited intentionally like so:

    @ Override void exit() {
      //my code here
      super.exit();
    }

But this, of course, is not called during a crash (I'm just trying to save the traceback to a file). Is there a way to do so without dozens of 'try' statements in my code?

Thanks in advance!!

Answers

  • I'm really not sure what happened to my first line of code... It's supposed to look like this '@Override void exit()'

  • fixed. forum tries to make any @ words into links to a user with that name. when this is in a code block you get to see the source. it's not very clever. use a space after the @ to stop it.

  • first, your sketch should not crash. Fix it.

    I'm just trying to save the traceback to a file

    second, if it is not possible to fix (or too much try-clauses) : you could save it throughout so when it crashes it just has the recent correct values

  • I'm trying to write a function that would be called if my processing sketch has crashed.

    Just to be clear, are you talking about a full JVM crash and its log/core/dump/mdmp ?

    Or are just talking about the sketch itself, and whether PDE already is writing a crash log somewhere -- or can redirect errors from the console?

  • Is there a way to do so without dozens of 'try' statements in my code?

    why dozens? won't a try...catch block around draw() suffice?

  • @koogs -- do you mean around the full contents of draw() -- that is, inside draw()?

    (I was trying to figure out how you could put draw() inside a try, but now I think that is not what you meant.)

  • yes, around the contents of draw(). that's the main loop, any errors will happen there

    (um, mousePressed() etc, i guess. depends on the code, which we haven't seen)

  • First of all, thanks you for all of your answers! I don't think I explained my question very well, as in why I need it to work the way it does.

    My code is somewhere in the vicinity of 20000 lines and growing, and as much of the testing will be done on different platforms after exporting, it is almost impossible to fix every potential bug. I'm trying to save the angry red text printed out by processing after a sketch crash. I can, as @koogs suggested, put a try statement around the entire draw() loop and save the exception, but then I get someting along the lines of 'java.lang.ArithmeticException: / by 0' - and I need a full traceback including line numbers, variable names, etc. Saving a list of values throughout the sketch is also impossible as a few of my variables are HashMaps with hundreds of millions of entries (I'm working on random terrain generation).

    In short, I'm trying to save the angry red text processing throws at me during an error in a fasion that would work after exporting the sketch.

    Thanks again!

  • Java does not provide some all-encompassing method that can be executed when the application crashes. In these situations Java throws exceptions and the user can deal with these using the try-catch mechanism.

    and as much of the testing will be done on different platforms after exporting,

    I'm working on random terrain generation

    If your application is just using the JRE i.e. standard Java language stuff and is not using any platform/OS dependent libraries then it can be tested on any single platform. Then you only need to worry about the export process producing the different OS flavoured applications

    As the name suggests throwing exceptions should be an exceptional occurrence.

    but then I get someting along the lines of 'java.lang.ArithmeticException: / by 0'

    You don't say what types of exceptions you are getting that cause your application to cash but you shouldn't be getting division by zero exceptions. In this case the software should catch and deal with this exception type or better still the algorithms used should be designed to avoid generating the error in the first place.

    The only possible solution that I can think might work would be for the sketch to redirect the System.err output stream from the console (default) to a file.

    Some google searches should find out how to do this.

  • Answer ✓

    e.printStackTrace() will give you a, er, stack trace. and that'll narrow it down to a file / method / line number.

    but beware, because of the pre-processing, it won't necessarily be the line in your pde that it points to, but rather the line number in the post-processed java file that was actually used in the compile.

  • 20000 lines

    that's too long. in 30+ years of doing this i've never written anything 20.000 lines long.

  • edited July 2017

    Thank you for all the answers! I now have a solution to my problem. This is my code:

    import java.io.*;
    void draw() {
      try {
        println(1/0);
      } catch (ArithmeticException e) {
        try {
          PrintStream ps = new PrintStream(sketchPath()+"\\data\\log.txt");
          e.printStackTrace(ps);
        } catch (FileNotFoundException not_gonna_happen) {
          println("file not found");
        }
        exit();
      }
    }
    

    Just a few comments:

    • @quark, the division-by-0-error was just an example, my code never gave me that. It was just easy to test using the code above. I tried the System.err method you suggested using System.setErr(myPrintStream) but that outputed this into the file __MOVE__ 110 226 -- did I do something terribly wrong?

    • @koogs, the 20000 lines is due to the fact that the project I'm working on has many different 'scenes', all of which are lengthy and do not use any of the same code. As for the line numbers being messed up, that can be rectified by simply exporting the sketch and then looking at the sketchname.java file in the source folder.

  • OK I have never done this before so it took some experimentation but try this and see if it does what you want.

    Press 'e' to simulate an uncaught exception

    import java.io.*;
    
    void setup() {
      size(300, 300);
      try {
        File file = new File(sketchPath() + "/" + "err.txt");
        //println(file.toString());
        FileOutputStream fos = new FileOutputStream(file);
        PrintStream ps = new PrintStream(fos);
        System.setErr(ps);
      }
      catch(Exception e) {
        e.printStackTrace();
      }
    }
    
    void draw() {
      try { 
        background(255);
        if (keyPressed && key =='e') {
          println("Crashing");
          simulateException();
        }
      }
      catch(RuntimeException e) {
        // In production code we would not have the try-cath statement 
        // here so the sketch would crash. This code simulates an 
        // uncaught exception
        e.printStackTrace(System.err);
        println("Program terminated");
        exit();
      }
    }
    
    // This meod simulates an Runtime Exception being thrown 
    // by the sketch.
    void simulateException() {
      throw new RuntimeException("Crash");
    }
    

    After pressing the 'e' key the err.txt file contained

    java.lang.RuntimeException: Crash
        at RedirectSystemError.simulateException(RedirectSystemError.java:52)
        at RedirectSystemError.draw(RedirectSystemError.java:40)
        at processing.core.PApplet.handleDraw(PApplet.java:2439)
        at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1547)
        at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:316)
    
Sign In or Register to comment.