Handling all exceptions in multiple threads

I want my program exceptions to be sent to each of the following, preferably at the same time:

  • the console that launches it (optional)
  • a gui
  • txt file.

How can i achieve this?

My attempts:

  • System.setErr(PrintStream err) will send all exceptions to the new stream. I cannot declare more than one thread, though.

  • Call System.setErr(PrintStream err) on a hand-written OutputStream :

    "You can write your own thread class that forwards multiple threads and calls System.setOut on an instance of this class" - Jeffrey Bosboom

    I found a way to do this. This is very unpleasant. It "collects" PrintStream write -bytes, puts them in a puffer (500 ms timeout), and finally shows it to the user ( Proceed ):

     /* ErrorOutput.java */ public static t_ErrBuffer t_activeErrBuffer = new t_ErrBuffer(""); public static void setStdErrToFile(final File file) { ps = new PrintStream(fos) { @Override public void write(byte[] buf, int off, int len) { byte[] bn = new byte[len]; for (int i = off, j = 0; i < (len + off); i++, j++) { bn[j] = buf[i]; } String msg = null; try { msg = new String(bn, "UTF-8"); } catch (UnsupportedEncodingException e1) {} if (msg.matches("[\\w\\W]*[\\w]+[\\w\\W]*")) { // ^= contains at least one word character if( ! t_activeErrBuffer.isAlive() ) { t_activeErrBuffer = new t_ErrBuffer(msg); t_activeErrBuffer.start(); } else { t_activeErrBuffer.interrupt(); t_activeErrBuffer = new t_ErrBuffer(t_activeErrBuffer.getErrBuffer() + "\n" + msg); // ^= append to buffer and restart. t_activeErrBuffer.start(); } } } }; System.setErr(ps); } /* t_ErrBuffer.java */ public class t_ErrBuffer extends Thread { private String errBuffer; public t_ErrBuffer(String buffer) { this.errBuffer = buffer; } protected class Proceed implements Runnable { public String msg = null; public Proceed(String msg) { this.msg = msg; } @Override public void run() { // todo PRINT ERROR MESSAGE: DO THINGS WITH msg: console, gui, JOptionPane } } @Override public void run() { try { Thread.sleep(500); // collect error lines before output. Needed because PrintStream "write"-method writes ErrorMessages in multiple pieces (lines) // each time some new exception line comes in, the thread is stopped, buffer is being appended and thread new started } catch (InterruptedException e) { return; // stop } // after 500 ms of wait, no new error message line has come in. Print the message out: Thread t_tmp = new Thread(new Proceed("\n" + this.errBuffer)); t_tmp.start(); return; } public String getErrBuffer() { return this.errBuffer; } } 

    Is this what I expect to do?

  • Create a new exception class that will do this for me. It will probably work, but other exceptions, apart from this (IO, FileNotFound, ...), will still be handled in the old way.

  • Instead of giving a [method name] throws Exception , I could wrap all my code in try / catch-blocks, get an exception, and redirect it to my method, for example:

     /* AnyMethod.java */ // ... try { // ... do everything here } catch (IOException | FileNotFoundException e) { // as many as you like ErrorOutput.crash(e); } // ... /* ErrorOutput.java */ public static void crash(Exception e) { FileOutputStream fos_errOutput = new FileOutputStream(new File("ErrorOutput.txt"), true); // 1st if (!System.out.equals(fos_errOutput)) { System.out.println(e.getMessage() + " :"); // to console or the preferred StdOut e.printStackTrace(); } // 2nd JOptionPane.showMessageDialog(Gui.frame, "THE PROGRAM HAS CRASHED!" + "\n\n" + e.getMessage() + "\n\nFor a more detailed report, see ErrorLog.txt"); // gui output // 3rd PrintStream ps = new PrintStream(fos_errOutput); ps.print(new Date().toString() + ":"); // write to file e.printStackTrace(ps); ps.close(); // 4th System.exit(0); // this could also be "throw new Exception" etc., but I don't know why one should do that. } 

    this will probably work as well, but I will have to paste everything into try / catch-blocks. This may not be a good programming style.

  • Registrar Use:

    "use log4j and configure the method for writing to the GUI, as well as for entering the stdout system and the file" - Scary Wombat

    Logs only help me print my exceptions to the right threads, but they don't help me catch them, right?

    But you really have to use the registration package for this - even java.util.logging can do whatever you need - Jeffrey Bosboom

    I must indicate my registration package, where and what to write. But this is exactly what I am looking for.

Now I can, as user3159253 suggested, use Thread.UncaughtExceptionHandler to catch unhandled exceptions.

What is the correct way to handle all thrown exceptions as I want them? What else should I consider separately from Thread.UncaughtExceptionHandler and System.setErr() (see above)?

+7
java exception throw stdout stderr
source share
2 answers

First you need to get all the exception instances that were thrown from / inside your thread (maybe try / catch or Thread.UncoughtExceptionHandler or ThreadPoolExecutor.afterExecute(Runnable r, Throwable t) ).

Then, as soon as you have an exception instance, you can simply register it with log4j, but configure Log4j applications to send exception messages to multiple destinations. Depending on your requirement, you can use file types, Consoles, JDBC, JMS, etc. It is also best to wrap them in an Async application.

Refer - https://logging.apache.org/log4j/2.x/manual/appenders.html

About pushing an exception message into the graphical interface can be implemented in various ways, depending on which technical stack you are using in your application. In our application, we store message events (only critical) in a database, which are then selected by the event monitoring flows from the server and then returned to the graphical interface (JQuery, JavaScript) using http://cometd.org/documentation/cometd-java .

+5
source share

Creating an object that extends PrintStream should work. Whenever he receives a string, he can display it and write it as necessary. Alternatively, all exceptions can be caught and redirected to a method that receives Exception as a parameter, and this method can take care of registering / displaying the exception and terminating the program.

+2
source share

All Articles