Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
Hello everyone,
I'm testing something. Here is a simple job for a REST API :
Here is the configuration of the upper tJavaRow, to throw an Exception using int i = 1/0;
From this point, we switch to the OnSubjobError branch.
The lower tRESTResponse :
I indeed get an error 500. Everything is ok.
In the console I get the expected Exception :
Exception in component tJavaRow_1 (api_err)
java.lang.ArithmeticException: / by zero
at talend_jobs_ua.api_err_0_1.api_err.tRESTRequest_1_LoopProcess(api_err.java:2959)
at talend_jobs_ua.api_err_0_1.api_err$RestServiceProviderImpl4TalendJob.processRequest(api_err.java:505)
at talend_jobs_ua.api_err_0_1.api_err$RestServiceProviderImpl4TalendJob.hello(api_err.java:615)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:201)
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:104)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:265)
at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:247)
at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:79)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1434)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:190)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:191)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:516)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
at java.base/java.lang.Thread.run(Thread.java:833)
I would like to know if there is a way to get this stack trace in a global variable or something else ?
Thank you for you light !
This method may work for you. You will need to test it thoroughly though. I've literally just tested this method on a theory that it would work.
Here is the quick service I've knocked up.....
Notice the tJava_1 at the beginning. Here is the code for that......
java.io.ByteArrayOutputStream baos = new ByteArrayOutputStream();
String utf8 = java.nio.charset.StandardCharsets.UTF_8.name();
System.setErr(new java.io.PrintStream(baos, true, utf8));
globalMap.put("baos", baos);
Then, on an error, we go to the tJavaFlex_2 which has this code in the Main Code section....
java.io.ByteArrayOutputStream baos = ((java.io.ByteArrayOutputStream)globalMap.get("baos"));
String utf8 = java.nio.charset.StandardCharsets.UTF_8.name();
String data = baos.toString(utf8);
baos.reset();
row2.error = data;
The tJavaFlex has an output column called error.
I tested this and it sends the error message to my XML output for the tRestResponse reporting the error.
This method may work for you. You will need to test it thoroughly though. I've literally just tested this method on a theory that it would work.
Here is the quick service I've knocked up.....
Notice the tJava_1 at the beginning. Here is the code for that......
java.io.ByteArrayOutputStream baos = new ByteArrayOutputStream();
String utf8 = java.nio.charset.StandardCharsets.UTF_8.name();
System.setErr(new java.io.PrintStream(baos, true, utf8));
globalMap.put("baos", baos);
Then, on an error, we go to the tJavaFlex_2 which has this code in the Main Code section....
java.io.ByteArrayOutputStream baos = ((java.io.ByteArrayOutputStream)globalMap.get("baos"));
String utf8 = java.nio.charset.StandardCharsets.UTF_8.name();
String data = baos.toString(utf8);
baos.reset();
row2.error = data;
The tJavaFlex has an output column called error.
I tested this and it sends the error message to my XML output for the tRestResponse reporting the error.
Hello @Richard Hall
Late answer from me.
I used a code I already have just to duplicate the output, sending it in the console and also in a global variable. (I use this code to duplicate out and err output in a txt file for my DI jobs, to keep a trace of Exceptions)
Here is the modified code, based on what you proposed :
First, commons.io must be imported :
tJava_1
java.io.ByteArrayOutputStream baos = new ByteArrayOutputStream();
String utf8 = java.nio.charset.StandardCharsets.UTF_8.name();
org.apache.commons.io.output.TeeOutputStream myOut = new org.apache.commons.io.output.TeeOutputStream(System.out, baos);
java.io.PrintStream ps = new java.io.PrintStream(myOut, true);
System.setOut(ps);
System.setErr(ps);
globalMap.put("baos", baos);
tJavaFlex_2
java.io.ByteArrayOutputStream baos = ((java.io.ByteArrayOutputStream)globalMap.get("baos"));
String utf8 = java.nio.charset.StandardCharsets.UTF_8.name();
String data = baos.toString(utf8);
baos.reset();
System.out.println("DATAAAAAAA : " + data);
So the Exception is displayed as usual in the console, and also set in baos global var !
Do you think the code is okay ?
It looks OK, but I've not tested it. If it works, then go with it....after rigorous testing 😉
It work at first sight at least !
I think this will last !
Thanks for you help @Richard Hall ! 🙂
Topic solved