I tried to execute jar from Java code with:
Runtime.getRuntime.exec("java -jar a.jar")
I could get InputStream with error from Process.getErrorStream().
Can I take this stream and if it has an Exception transform it to Exception and throw in my upper application?
Has Java some mechanism to convert string to Exception?
EDIT: Or maybe java has some mechanism like System.exit(int code) but with Exception? So in parent app I can do something like process.waitFor() but take an exception instead int code?
Process.getErrorStream() returns an IntputStream connected to the error output of the subprocess.
So, it is not exception in Java terms. It's an output information which must be considered as an error detected by the process during its execution.
Java don't convert automatically InputStream or String to Exception.
So, you could read this stream in a String and throw a custom exception with as message the string.
If you want that the caller may be able to handle this exception in a clean way, don't use a RuntimeException but a checked exception :
public class ProcessExecutionException extends Exception{
public ProcessExecutionException(String errorOutputMsg){
super(errorOutputMsg);
}
}
Edit for answering your comment :
Yeah, but how to check is inputstream line is a part of stacktrace of
child exception
it's not a stracktrace but error messages as explained.
and how much line from IS i should add to ProcessExecutionException?`
You have to read all the errorStream until it returns null if you want to capture all error output.
In my case my jar is a Spring Application and it write to error stream
nor only Exception that i really need to catch, also some information
like "Error, you have no sl4j xml file, etc - like example". And i
need only really important exception
How the classes producing errors in output may guess if it is important for you or not ?
You must decide yourself which error message pattern should be considered as an important error or not.
Personally, if when my process is run, I have a not well configured logger, I will kill it and correct this problem before starting it again.
If you have input in the ErroStream, you can also inspect the value of the Process.exitCode() (0: normal termination, else problem).
If it is different from 0, you can suspect that it not only a little problem.
Here, some tracks to try.
Can i return something to exit like in System.exit()
In the child process, you can try to intercept all exceptions not handled which may be triggered . You can do it whatever the way (aspect, global try/catch, filter...) .
In this way, if you intercept an exception not handled and that you consider that the application must be terminated, you can do a System.exit with the expected code by the parent process.
In this way, in the parent, if Process.exitCode() matchs with expected code for important exception, you can handle it as you wish.
Related
In regards to Log4j v2, I'd like to call log.error(exceptionTypeObj) and have the stack trace printed to my logfile instead of exceptionTypeObj.toString(). Is that possible?
I'd rather write code like log.error(e) and be done with it.
It's error prone and redundant for me to keep writing something like log.error("error", exceptionTypeObj).
The String parameter is redundant because you are not using it for the correct purpose. An Exception will tell you what error occurred but it won't tell you what you were trying to do when it happened. That is why you should always provide the string. Provide a String that says something like "Error occurred while attempting to update the user profile for user {}", and then provide the user name or id.
Without the String parameter you are forcing your support staff to call engineering to find out what the exception means and what they should do about it.
I often get this kind of Exception
Exception in thread "main" org.neo4j.driver.v1.exceptions.TransientException: LockClient[21902] can't wait on resource RWLock[NODE(1423923), hash=286792765] since => LockClient[21902] <-[:HELD_BY]- RWLock[NODE(1419986), hash=869661492] <-[:WAITING_FOR]- LockClient[21905] <-[:HELD_BY]- RWLock[NODE(1423923), hash=286792765]
when I run Neo4j queries in my Java application. Now, this question has a good answer to the reason why this error occurs, and I can't do anything to improve my queries: I just need them as they are.
My question is: how can I catch this kind of exception? It occurs at this line of my code:
session.run(query, parameters);
but the Javadoc doesn't show any apparent Exception to be catched with a try-catch block.
Thanks in advance.
This is because TransientException is a runtime exception (E.G. a subclass of Java.lag.RuntimeException). It is not required to be in the method signature, and you are not required to put he method in a Try...Catch block. Try putting that line within a try...catch block and you should not get that exception anymore. How you handle it depends on the nature of your application. You could print a warning to log, and then error in the application, or even keep trying until the code worked.
Edit: after reading the answer you linked, I understand why you are getting these exceptions. I would put a Thread.sleep() in the catch block, then attempt the query again, in which case the error should go away. But then again, I am in no way a Neo4j expert so take my advice with a grain (truckload ) of salt
Edit 2: your code should look somewhat like this:
for(Query query : queries){
boolean flag = false;
while(!flag){
try{
query.execute();
flag = true;
} catch (TransientException e){
log("Retrying query "+query);
Thread.sleep(1*1000); //1 second
}
}
}
I have this specific scenario:
my exceptions have a code and a localized message
The thrower just knows the code
The catcher expects a localized message
The localization is inside of a DB table
Would it be wrong something like this:
public class MyException{
public MyException(int code){
try{
this.message = db.selectMessage(code);
}catch(Exception ex){
this.message = "";
}
}
}
This would completely hide from the thrower the fact that the message is localized.
Alternatively I should go with something like this:
public class ExceptionUtils{
public static throwMyException(int code) throws MyException{
String message = db.selectMessage(code);
throw new MyException(code, message);
}
}
But this requires the thrower to know about this util.
I would suggest using ResourceBundle class as it is widely accepted way for localization. This way you store your messages in files as oppose to DB. Also reading your messages from those files is handled by JVM and you don't have to write your own code for it. However, if you insist on using DB, I would sudgest to read all your messages from DB into file system or onto your memory during your app initialization and then you don't have to read from DB and risk DB connectivity failure for each exception.
This is a better approach:
public class MyException extends Exception {
private int code;
public MyException(String message, int code) {
super(message);
this.code = code;
}
public int getCode() {
return code;
}
}
Usage:
Integer messageCode = null;
try {
// do stuff
} catch (MyException e) {
logger.log(e.getMessage(), e); // log actual message
messageCode = e.getCode();
}
if(messageCode != null /* && you really want to show it to end user */) {
String localizedMessage = db.selectMessage(code);
// show localized message to end user
}
Adavantages:
You don't need a Util class to throw exceptions.
You don't need to access db every time you throw an exception but
only when you catch it and "decide" to fetch the message if you want
to show it to user.
You don't need to catch an exception inside another exception.
You don't lose the actual non-localized message.
You don't lose actual stack trace in case db.getMessage() fails and throws exception.
Edit:
There is a dispute about whether the if part is a good idea or not so I have to elaborate.
message and localized version of message, these are very different.
Message:
is a description of what has gone wrong.
is what you see in console and in log records when exception occurs.
is in English.
must be shown regardless of any conditions and if not shown it's considered a very bad practice.
Localized Message:
is a translation of Message for the benefit of End User and not programmer.
is not in English.
is not expected to be shown either in console or log records.
is only needed when interacting with End User in UI.
is not expected to be used in non-UI related parts of code.
In the actual code provided by asker, message is replaced by localized message which violates expected behavior of a well-designed exception so I separated these two. In my code the message is Always shown and can be logged whenever exception occurs regardless of any conditions; Fetching localized message occurs only IF you actually need to interact with End Users. So access to DB can be skipped when you are not interacting with them.
the catch block is designed to do some actions after an exception occurs in your program, hence i would recommend you to provide some of the exception handling code in the catch block as it will allow others to understand your program efficiently
It is not bad as long it is code that helps you best handle the exception
The problem is one of too many moving parts. If your database access within the catch block fails by throwing an exception - and it can fail for any one of a number of reasons - then you won't ever see even your original exception. The same goes for anything you do in the catch block that could itself throw an exception.
This has recently happened to me, in fact, in legacy code (different language though same idea). Man is that a pain when you know your production system is failing for some specific reason but you have no idea what that specific reason is ...
It may be the case that your routine db.selectMessage() is itself protected against and won't throw an exception. Ok then. But it's going to be your responsibility to check that in every catch block you write. It's better to go with a design approach that doesn't involve catch blocks that do much of anything except things known to be 'safe'.
In some languages, by the way, catching all exceptions catches some really nasty ones (in Java, those aren't usually subclasses of java.lang.Exception though). And sometimes you really don't want to do anything unnecessary, 'cause you don't know what state you're in and what'll happen.
In this case, you're probably going to be logging that exception somewhere (or otherwise notifying the user). That logging code is (or should be) centralized in your application. That's the place to carefully translate/localize/interpret the exception code ... someplace where in one place you can make sure it works and is protected ... same as the logging code itself.
My question is: it better to log with getMessage or with toString or both? taking in to account errors thrown by open source. Saw the questions in the comments but did not get an answer to this. Maybe I missed something ? Do not mind the small performance hit of logging one of them, but do not want to log both unless there is a good reason.
Meaning log(ex) or log(ex.getMessage), Not talking about stack trace.
Saw 1 , 2 and 3
Logging exceptions : which is better:
log.warn(ex.getMessage(), ex) or log.warn(ex, ex);
I noticed sometimes getMessage returns empty or null, so in general practice is there any reason not to use :
log.warn(ex, ex);
As it seems to print the class name and the message (if set) ? I guess one reason could be if a sub class has over ridden to string not to print the message, but in reality do any of the hibernate, apache or spring libs do that?
How about
log.warn("some descriptive message, maybe with context {}",
someId, ex);
The exception details will already be printed as part of the stacktrace, so you don't need to include them in the message usually.
In case you want to suppress the stacktrace and only print the exception message, usually, ex.toString() works better than ex.getMessage(), because it also includes the exception class name, which the message does not. In fact, often the message is empty (for example with NullPointerExceptions).
I'm currently dealing with exceptions handling and I'm wondering where should I catch them.
Here is an stack from the GWT app :
A helper with a method which can throws NumerFormatExeption
(FormHelper.java)
A widget which uses this helper (CostWidget.java)
A presenter which calls this widget to retrieve data (BuildingPresenter.java)
FormHelper.java
public static Integer prepareIntegerForDb(String string) {
return Integer.parseInt(string);
}
CostWidget.java
public DetailCostProxy getCostDetail() {
...
costDetail.setQuantity(FormHelper.prepareDoubleForBd(qtTextBox.getText()));
...
return costDetail;
}
public List<DetailCostProxy> getCostList() {
...
costDetails .add(ligneCout.getCostDetail());
...
}
BuildingPresenter.java
public void saveBuilding(final BuildingProxy inter, final CollectRequestContext savecontext) {
savecontext.save(display.getCostWidget().getCoutList()).fire(new Receiver<BuildingProxy >() {....
}
I am thinking about :
1) adding "throws NumberFormatException" to prepareIntegerForDb() in the helper
2) adding "throws NumberFormatException" to getCostDetail() in the widget
3) adding "throws NumberFormatException" to getCostList() in the widget
4) caching the exception in the presenter (in saveBuilding)
The aim is :
to log the exception
to provide the user with a message saying that something went wrong
What do you think about this approach considering that this in an example and I will have to apply this pattern into the entire app (more than 20 presenters).
Is my way a good way to handle exceptions in GWT ? or should I log the error directly in the helper or elsewhere ?
prepareIntegerForDB() should throw the exception. This happens automatically when Integer.parse() fails, and you do not have to actually throw the Exception.
getCostDetail() should explicitly catch and throw the exception, and possibly expand upon why it was thrown. Something like "The cost was not in a readable format". That method is responsible for only that one line.
getCostList() should catch and handle the exceptions. That method is responsible for an entire collection. If you do not handle the bad data here, you will lose the good data. Here is one way to handle the bad data.
public List<DetailCostProxy> getCostList() {
...
try {
DetailCostProxy cost = lineCount.getCostDetail()
costDetails.add(cost);
catch (NumberFormatException e) {
costDetails.add(null);
}
...
}
Finally, the method that displays your data to the user should interpret the data passed to it before displaying it. If you used my example above, this would be as simple as checking for null values.
What do you think about this approach considering that this in an
example and I will have to apply this pattern into the entire app
(more than 20 presenters).
Adding throws NumberFormatException declarations won't help you to "provide the user with a message saying that something went wrong". NumberFormatException-s are RuntimeException-s so the throws declaration won't even force to try/catch in the code that uses these methods.
Is my way a good way to handle exceptions in GWT ? or should I log the
error directly in the helper or elsewhere ?
4) catching the exception in the presenter (in saveBuilding)
The aim is :
to log the exception
to provide the user with a message saying that something went wrong
This question is not specific to GWT.
To catch the Exception is a good idea if you know how to deal with it.
If you signal the error to the user, you need to be able to have the user decide how to handle the issue (for example a pop-up message proposing two actions to resume the application execution).