I have a try/catch thing set up where it will catch all exceptions and then display the error.
Here is my code:
try {
//CODE THAT COULD ERROR HERE
} catch (final Exception e) {
System.err.println("Unexpected error: " + e.getStackTrace()[0]);
}
The above code gives me the LAST class that had the error. How do I detect the LAST class of MY PROGRAM that had the error?
Example Output: "Unexpected error: package.ClassName.method(ClassName.java:46)"
I want it to output the line of my program that had the error, not the line of a built-in java class that error-ed because of my program.
e.printStackTrace()
might make you happier. Or print the top of the array of stack trace entries available from the appropriate method.
http://docs.oracle.com/javase/6/docs/api/java/lang/Throwable.html#getStackTrace()
returns them. The first one is what you are asking for.
You can use getStackTrace to get an array of StackTraceElement instances, and filter that based on your package and/or class names (using getClassName for each element, which gives you the fully-qualified class name for that stack trace frame). That would let you winnow it down to your code rather than the JDK class the exception originated in.
try {
//error producing code
} catch (Exception e) {
for (StackTraceElement s : e.getStackTrace()) {
if (!s.getClassName().startsWith("java.")) {
System.out.println("file name: " + s.getFileName());
System.out.println("class name: " + s.getClassName());
System.out.println("method name: " + s.getMethodName());
System.out.println("line number: " + s.getLineNumber());
System.out.println();
//break; // will be the highest non java package...
}
}
}
You of course could switch it to be package specific so if (s.getClassName().startsWith("com.company")) { so it wont return for a third party library or something in the sun package or other non java package.
Related
Hi all I know its a stupid question but I'm trying everything.
My game server show me a very long error which is too long for console and can see the top of it, but it is missing from my log and I can't see the details of this error.
Can somebody help me on how can I capture that error:
private void fix(L2PcInstance pl, int playerPoints)
{
try
{
IAchievement arc = Achievements.getInstance().GetAchivment(_id, pl.getAchivmentLevelbyId(_id) + 1);
if ((arc != null) && (playerPoints > arc.getNeedPoints()))
{
Achievements.getInstance().reward(pl, arc);
fix(pl, playerPoints);
}
}
catch (Exception e)
{
_log.error(getClass().getSimpleName() + ": Error in fix: " + e);
}
}
the error
the line 96 is
fix(pl, playerPoints);
but the error is missing from my log im try to capture the console to txt file from command
java myserver.jar > capturemyconsole.txt but again it's showing error in console that the txt is missing. How is this possible ? Thanks for your time and help :)
and sorry for my bad english :(
You method fix calls itself, with the same arguments, causing stack overflow...
Should add some modification to the arguments, or some more condition to the recursion...
You can catch "Error" instead of "Exception" and then log
[...] catch (Error e)
{
_log.error(getClass().getSimpleName() + ": Error in fix: " + e, e);
}
In Your current code StackOverflowException (which is not a child of Exception) is propagated without going into catch block. Remember to put additional "e" parameter to log full stacktrace.
It's not a good practice to catch Error, but it'll answer Your question.
More info: try/catch on stack overflows in java?
Please don't hesitate to edit the question or to ask more details about the questin.
I know I can log the ArithmeticException of the below method using the aspectJ as,
public void afterThrowingAspect(){
System.out.println("This is afterThrowingAspect() !");
int i=2/0;
System.out.println("i value : "+i);
}
The AspectJ class has,
#AfterThrowing(pointcut = "execution(* com.pointel.aop.test1.AopTest.afterThrowingAspect(..))",throwing= "error")
public void logAfterError(JoinPoint joinPoint,Throwable error) {
System.out.println("Hi jacked Method name : " + joinPoint.getSignature().getName());
log.info("Method name : " + joinPoint.getSignature().getName());
log.info("Error report is : " + error);
}
Normally I can handle exception using the TRY and CATCH block and log the errors in the every CATCH block as ,
public void someMehtod(){
try{
int i=2/0;
System.out.println("i value : "+i);
}catch{ArithmeticException err){
log.info("The exception you got is : " + err);
}
}
But I don't like to do the logging like with every single catch block individually in all the java classes of my project like ,
log.info("The exception you got is : " + err);
I would like to do the logging inside CATCH block in my application using the aspectJ class.
Hope you are all understand my question.Thanks.
Its possible to simply remove the try/catch from your code and simply log the exception in your aspect.
public void someMehtod(){
int i=2/0;
System.out.println("i value : "+i);
}
Because you don't re-throw the exception in the aspect then it won't bubble up. Although this is possible I strongly advise you to think more about what you are trying to do here. Why do you need to log the fact that an exception has been thrown? Exceptions aren't necessarily only for errors but can occur in normal code journeys. Simply logging only the exception name is unlikely to help you debug the problem. Therefore, you will probably want a bespoke log message for each catch block. If you do find repetition you could create a method to log out the result.
Hope this helps,
Mark
I've some problem printing the exception stack trace for Alfresco Exception.
On debug mode, step by step under Eclipse IDE I'm able to see the message when the exception is raised inspecting the Exception object but, when I send the error message to console output it's always null.
The exception is raised by this instruction:
try {
UpdateResult[] results = WebServiceFactory.getRepositoryService().update(cml);
}
catch (Exception ex) {
System.out.println(" " + ex.getStackTrace());
System.out.println("ERROR - createContent : " + ex.getMessage());
}
(in that case I tryed to write on a folder that not exists on repository) and inspecting the ex object on eclipse I can see the message:
java.lang.IllegalStateException: Failed to resolve to a single NodeRef with parameters (store=workspace:SpacesStore uuid=null path=/app:company_home/cm:UploadFromJava), found 0 nodes.
but ex.getMessage() returns null
Anyone could help me?
thanks,
Andrea
Implementing a method in this way:
NamedValue setNameProperty(String name) throws AlfrescoRuntimeException
{
try {
return Utils.createNamedValue(Constants.PROP_NAME, name);
}
catch (Exception ex) {
throw new AlfrescoRuntimeException(ex.getMessage());
}
}
The message is correclty printed with e.printStackTrace();
Try to replace your package in the log4j.properties from debug to error
I am having a LDAP Queue which process a object class.I cant find the exact location why it is giving the exception. The objclass is a concadenation string with pipe symbol. Any program coding to find the exact location in which concadination part is going to the Exception?.Please Assist.
try {
Attributes objClass = null;
try {
objClass = getObjClass(LdapInfo.PER_ID, person.perId);
} catch (NamingException e)
{
DCXError.myInstance().writeError("LdapUpdaterConnection: " + e.getMessage());
}
NamingEnumeration oc = objClass.get("objectclass").getAll();
String baseObjClass = null;
while (oc.hasMoreElements()) {
baseObjClass = (String) oc.nextElement();
if (baseObjClass.equalsIgnoreCase(LdapInfo.NON_EMPLOYEE_PERSON)
|| baseObjClass.equalsIgnoreCase("N/A")||
baseObjClass.equalsIgnoreCase(LdapInfo.EMPLOYEE_PERSON))
break;
}
} catch (SchemaViolationException e4) {
DCXError.myInstance().writeError(
"LdapUpdaterConnection:doUpdate SchemaViolationException "+ e4.getExplanation());
DCXError.myInstance().writeError("LdapUpdaterConnection:update persID = " + personId);
return (LdapUpdaterConnection.BAD_DATA);
}
You can't find the exact location only because you haven't logged the stack trace. You would also need to reformat your code so that each statement is on a separate line to make any use of that information. You should also use variable names that actually correspond to the content.
This is really terrible code.
It's also hard to see why you are doing all this in the first place. A decent query filter would do all that for you far more simply.
I have a generic function that prints exceptions (using log4j):
private void _showErrorMessage(Exception e) {
log.error(e.getClass() + ": " + e.getMessage() + ": " + e.getCause() + "\n" + e.getStackTrace().toString());
}
Instead of seeing the stack trace I'm seeing:
[Ljava.lang.StackTraceElement;#49af7e68
How can I view the stack trace of the exception properly?
update
log.error(e) <- shows the error, but doesn't show stack trace
Your logging framework should have the ability to log exceptions, so simply passing the exception to the proper .error(Object, Throwable) call should be enough:
log4j can do it
commons logging can do it
java.util.logging can do it
If your logging framework can't do that, or you need the stack trace in a String for any other reason, then it becomes a bit harder. You'll have to create a PrintWriter wrapping a StringWriter and call .printStackTrace() on the Exception:
StringWriter sw = new StringWriter();
ex.printStackTrace(new PrintWriter(sw));
String stacktrace = sw.toString();
Have you tried?
private void _showErrorMessage(Exception e) {
log.error("Hey! got an exception", e);
}
I use the ExceptionUtils#getFullStackTrace method of Jakarta Commons Lang
Throwable.getStackTrace returns an array of StackTraceElements, hence the toString method is returning a textual representation of the array itself.
In order to actually retrieve the stack trace information, one would have to go through each StackTraceElement to get more information.
You could also look at the Guava libraries from Google.
Throwables.getStackTraceAsString(Throwable throwable)
The exact answer to your question is that you should call Log4J like this:
private void _showErrorMessage(Exception e) {
log.error(e.getClass() + ": " + e.getMessage() + ": " + e.getCause(), e);
}
Although I would dispense with the call to e.getCause() because the stacktrace will give that to you anyway, so:
private void _showErrorMessage(Exception e) {
log.error(e.getClass() + ": " + e.getMessage(), e);
}
ExceptionUtils is fine if you really need a string of the stacktrace, but since you are using Log4J, you lose a lot by not utilizing its built in exception handling.
Exception Stacktrace logging shows two methods for this purpose, one based on Apache Commons and another using the standard JDK method.