001    package railo.runtime.exp;
002    
003    import java.io.IOException;
004    import java.io.PrintStream;
005    import java.io.PrintWriter;
006    import java.io.StringWriter;
007    import java.lang.reflect.InvocationTargetException;
008    import java.util.Iterator;
009    import java.util.LinkedList;
010    
011    import railo.commons.io.IOUtil;
012    import railo.commons.io.res.Resource;
013    import railo.commons.io.res.util.ResourceUtil;
014    import railo.commons.lang.StringUtil;
015    import railo.runtime.Info;
016    import railo.runtime.PageContext;
017    import railo.runtime.PageContextImpl;
018    import railo.runtime.PageSource;
019    import railo.runtime.config.Config;
020    import railo.runtime.dump.DumpData;
021    import railo.runtime.dump.DumpProperties;
022    import railo.runtime.dump.DumpTable;
023    import railo.runtime.dump.DumpTablePro;
024    import railo.runtime.dump.SimpleDumpData;
025    import railo.runtime.engine.ThreadLocalPageContext;
026    import railo.runtime.err.ErrorPage;
027    import railo.runtime.op.Caster;
028    import railo.runtime.type.Array;
029    import railo.runtime.type.ArrayImpl;
030    import railo.runtime.type.Collection;
031    import railo.runtime.type.KeyImpl;
032    import railo.runtime.type.List;
033    import railo.runtime.type.Struct;
034    import railo.runtime.type.StructImpl;
035    import railo.runtime.type.dt.DateTimeImpl;
036    import railo.runtime.writer.CFMLWriter;
037    
038    /**
039     * Railo Runtime Page Exception, all runtime Exception are sub classes of this class
040     */
041    public abstract class PageExceptionImpl extends PageException {
042    
043            private static final Collection.Key RAW_TRACE = KeyImpl.intern("raw_trace");
044            private static final Collection.Key CODE_PRINT_HTML = KeyImpl.intern("codePrintHTML");
045            private static final Collection.Key CODE_PRINT_PLAIN = KeyImpl.intern("codePrintPlain");
046            
047            
048            
049            
050            private Array tagContext=new ArrayImpl();
051            private Struct additional=new StructImpl(Struct.TYPE_LINKED);
052            /**
053             * Field <code>detail</code>
054             */
055            protected String detail="";
056            //private Throwable rootCause;
057            private int tracePointer;
058            private String errorCode="0";
059            private String extendedInfo=null;
060    
061            private String type;
062            private String customType;
063            private boolean isInitTagContext=false;
064            private LinkedList sources=new LinkedList();
065            private String varName;
066    
067    
068            /**
069             * Class Constructor
070             * @param message Exception Message
071             * @param type Type as String
072             */
073            public PageExceptionImpl(String message,String type) {
074                    this(message,type,null);
075            }
076            /**
077             * Class Constructor
078             * @param message Exception Message
079             * @param type Type as String
080             * @param customType CUstom Type as String
081             */
082            public PageExceptionImpl(String message,String type, String customType) {
083                    super(message==null?"":message);
084                    //rootCause=this;
085                    this.type=type.toLowerCase().trim();
086                    this.customType=customType;
087            //setAdditional("customType",getCustomTypeAsString());
088            }
089            
090            /**
091             * Class Constructor
092             * @param e exception
093             * @param type Type as String
094             */
095            public PageExceptionImpl(Throwable e,String type) {
096                    this(e,type,null);
097            }
098            
099            /**
100             * Class Constructor
101             * @param e exception
102             * @param type Type as String
103             * @param customType CUstom Type as String
104             */
105            public PageExceptionImpl(Throwable e,String type, String customType) {
106                    super(StringUtil.isEmpty(e.getMessage(),true)?e.getClass().getName():e.getMessage());
107                    if(e instanceof InvocationTargetException)e=((InvocationTargetException)e).getTargetException();
108            
109            //this.i
110            initCause(e);
111            //this.setStackTrace(e.getStackTrace());
112            
113                    if(e instanceof IPageException) {
114                IPageException pe=(IPageException)e;
115                            this.additional=pe.getAddional();
116                            this.setDetail(pe.getDetail());
117                            this.setErrorCode(pe.getErrorCode());
118                            this.setExtendedInfo(pe.getExtendedInfo());
119                    }
120                    
121                    //else if(e.getCause()!=null)rootCause=e.getCause();
122                    //else rootCause=e;
123    
124                    this.type=type.trim();
125                    this.customType=(customType==null)?this.type:customType;
126            }
127        
128        /**
129         * @see railo.runtime.exp.PageException#getDetail()
130         */
131            public String getDetail() { 
132                    if(detail==null || detail.equals(getMessage()))return "";
133                    return detail; 
134            }
135            
136            /**
137         * @see railo.runtime.exp.PageException#getErrorCode()
138         */
139            public String getErrorCode() { return errorCode==null?"":errorCode; }
140            
141            /**
142         * @see railo.runtime.exp.PageException#getExtendedInfo()
143         */
144            public String getExtendedInfo() { return extendedInfo==null?"":extendedInfo; }
145            
146            /**
147             * @see railo.runtime.exp.IPageException#getTypeAsString()
148             *
149            public abstract String getTypeAsString();*/
150            
151    
152            /**
153         * @see railo.runtime.exp.PageException#setDetail(java.lang.String)
154         */
155            public void setDetail(String detail) {
156                    this.detail=detail;
157            }
158            /**
159         * @see railo.runtime.exp.PageException#setErrorCode(java.lang.String)
160         */
161            public void setErrorCode(String errorCode) {
162                    this.errorCode=errorCode;
163            }
164            /**
165         * @see railo.runtime.exp.PageException#setExtendedInfo(java.lang.String)
166         */
167            public void setExtendedInfo(String extendedInfo) {
168                    this.extendedInfo=extendedInfo;
169            }
170            
171            /**
172             * @see railo.runtime.exp.IPageException#getCatchBlock()
173             */
174            public final Struct getCatchBlock() {
175                    return getCatchBlock(ThreadLocalPageContext.getConfig());
176            }
177            
178            /**
179             *
180             * @see railo.runtime.exp.IPageException#getCatchBlock(railo.runtime.PageContext)
181             */
182            public final Struct getCatchBlock(PageContext pc) {
183                    return getCatchBlock(ThreadLocalPageContext.getConfig(pc));
184            }
185            
186            /*
187             * FUTURE add to interface
188             */
189            public CatchBlock getCatchBlock(Config config) {
190                    return new CatchBlock(this);
191            }
192            
193            public Array getTagContext(Config config) {
194                    if(isInitTagContext) return tagContext;
195                    _getTagContext( config,tagContext,this,sources);
196                    isInitTagContext=true;
197                    return tagContext;
198            }
199            
200    
201            public static Array getTagContext(Config config,StackTraceElement[] traces) {
202                    Array tagContext=new ArrayImpl();
203                    _getTagContext( config,tagContext,traces,new LinkedList());
204                    return tagContext;
205            }
206            
207    
208            private static void _getTagContext(Config config, Array tagContext, Throwable t, LinkedList sources) {
209                    _getTagContext(config, tagContext, getStackTraceElements(t), sources);
210            }
211            
212            private static void _getTagContext(Config config, Array tagContext, StackTraceElement[] traces, 
213                            LinkedList sources) {
214                    //StackTraceElement[] traces = getStackTraceElements(t);
215                    
216                    int line=0;
217                    String template="",tlast;
218                    Struct item;
219                    StackTraceElement trace=null;
220                    int index=-1;
221                    PageSource ps;
222                    for(int i=0;i<traces.length;i++) {
223                            trace=traces[i];
224                            tlast=template;
225                            template=trace.getFileName();
226                            if(trace.getLineNumber()<=0 || template==null || ResourceUtil.getExtension(template,"").equals("java")) continue;
227                            // content
228                            if(!StringUtil.emptyIfNull(tlast).equals(template))index++;
229                            
230                            String[] content=null;
231                            try {
232                                    
233                                    Resource res = config.getResource(template);
234                                    
235                                    // never happens i think
236                                    if(!res.exists()) {
237                                            res = ResourceUtil.toResourceNotExisting(ThreadLocalPageContext.get(), template);
238                                    }
239                                     
240                                    if(res.exists())        
241                                            content=IOUtil.toStringArray(IOUtil.getReader(res,config.getTemplateCharset()));
242                                    else {
243                                            if(sources.size()>index)ps=(PageSource) sources.get(index);
244                                            else ps=null;
245                                            if(ps!=null && trace.getClassName().equals(ps.getFullClassName())) {
246                                                    if(ps.physcalExists())
247                                                            content=IOUtil.toStringArray(IOUtil.getReader(ps.getPhyscalFile(), config.getTemplateCharset()));
248                                                    template=ps.getDisplayPath();
249                                            }
250                                    }       
251                            } 
252                            catch (Throwable th) {
253                                    //th.printStackTrace();
254                            }
255                            
256                            // check last
257                            if(tagContext.size()>0){
258                                    try {
259                                            Struct last=(Struct) tagContext.getE(tagContext.size());
260                                            if(last.get(RAW_TRACE).equals(trace.toString()))continue;
261                                    } 
262                                    catch (Exception e) {
263                                            //e.printStackTrace();
264                                    }
265                            }
266                            
267                            item=new StructImpl();
268                            line=trace.getLineNumber();
269                            item.setEL(KeyImpl.TEMPLATE,template);
270                            item.setEL(KeyImpl.LINE,new Double(line));
271                            item.setEL(KeyImpl.ID,"??");
272                            item.setEL(RAW_TRACE,trace.toString());
273                            item.setEL(KeyImpl.TYPE,"cfml");
274                            item.setEL(KeyImpl.COLUMN,new Double(0));
275                            if(content!=null) {
276                                    item.setEL(CODE_PRINT_HTML,getCodePrint(content,line,true));
277                                    item.setEL(CODE_PRINT_PLAIN,getCodePrint(content,line,false));
278                            }
279                            else {
280                                    item.setEL(CODE_PRINT_HTML,"");
281                                    item.setEL(CODE_PRINT_PLAIN,"");
282                            }
283                            // FUTURE id 
284                            tagContext.appendEL(item);
285                    }
286            }
287            
288            
289            
290            public int getPageDeep() {
291                    StackTraceElement[] traces = getStackTraceElements(this);
292                    
293                    String template="",tlast;
294                    StackTraceElement trace=null;
295                    int index=0;
296                    for(int i=0;i<traces.length;i++) {
297                            trace=traces[i];
298                            tlast=template;
299                            template=trace.getFileName();
300                            if(trace.getLineNumber()<=0 || template==null || ResourceUtil.getExtension(template,"").equals("java")) continue;
301                            if(!StringUtil.emptyIfNull(tlast).equals(template))index++;
302                            
303                    }
304                    return index;
305            }
306            
307            
308            /**
309         * @see railo.runtime.exp.PageException#getErrorBlock(railo.runtime.PageContext, railo.runtime.err.ErrorPage)
310         */
311            public Struct getErrorBlock(PageContext pc,ErrorPage ep) {
312                    Struct struct=new StructImpl();
313    
314                    struct.setEL("browser",pc.cgiScope().get("HTTP_USER_AGENT",""));
315                    struct.setEL("datetime",new DateTimeImpl(pc));
316                    struct.setEL("diagnostics",getMessage()+' '+getDetail()+"<br>The error occurred on line "+getLine(pc.getConfig())+" in file "+getFile(pc.getConfig())+".");
317                    struct.setEL("GeneratedContent",getGeneratedContent(pc));
318                    struct.setEL("HTTPReferer",pc.cgiScope().get("HTTP_REFERER",""));
319                    struct.setEL("mailto",ep.getMailto());
320                    struct.setEL("message",getMessage());
321                    struct.setEL("QueryString",StringUtil.emptyIfNull(pc. getHttpServletRequest().getQueryString()));
322                    struct.setEL("RemoteAddress",pc.cgiScope().get("REMOTE_ADDR",""));
323                    struct.setEL("RootCause",getCatchBlock(pc));
324                    struct.setEL("StackTrace",getStackTraceAsString());
325                    struct.setEL("template",pc. getHttpServletRequest().getServletPath());
326                    
327                            struct.setEL("Detail",getDetail());
328                            struct.setEL("ErrorCode",getErrorCode());
329                            struct.setEL("ExtendedInfo",getExtendedInfo());
330                            struct.setEL("type",getTypeAsString());
331                            struct.setEL("TagContext",getTagContext(pc.getConfig()));
332                            struct.setEL("additional",additional);
333                            // TODO RootCause,StackTrace
334                    
335                    return struct;
336            }
337            
338            private String getGeneratedContent(PageContext pc){
339                    PageContextImpl pci=(PageContextImpl)pc;
340                    CFMLWriter ro=pci.getRootOut();
341                    String gc=ro.toString();
342                    try{
343                            ro.clearBuffer();
344                    }
345                    catch(IOException ioe){}
346                    if(gc==null) return "";
347                    return gc;
348            }
349            
350            
351            /**
352             * @return return the file where the failure occurred
353             */
354            private String getFile(Config config) {
355            if(getTagContext(config).size()==0) return "";
356            
357            Struct sct=(Struct) getTagContext(config).get(1,null);
358            return Caster.toString(sct.get("template",""),"");
359        }
360        /**
361         * @see railo.runtime.exp.PageException#getLine()
362         */
363            public String getLine(Config config) {
364            if(getTagContext(config).size()==0) return "";
365            
366            Struct sct=(Struct) getTagContext(config).get(1,null);
367            return Caster.toString(sct.get("line",""),"");
368        }
369        /**
370         * @see railo.runtime.exp.PageException#addContext(railo.runtime.PageSource, int, int)
371         */
372            public void addContext(PageSource pr, int line, int column, StackTraceElement element) {
373                    if(line==-187) {
374                            sources.add(pr);
375                            return;
376                    }
377            
378                    Struct struct=new StructImpl();
379            //print.out(pr.getDisplayPath());
380                    try {
381                            String[] content=pr.getSource();
382                            struct.set("template",pr.getDisplayPath());
383                            struct.set("line",new Double(line));
384                            struct.set("id","??");
385                            struct.set("Raw_Trace",(element!=null)?element.toString():"");
386                            struct.set("Type","cfml");
387                            struct.set("column",new Double(column));
388                            if(content!=null){
389                                    struct.set("codePrintHTML",getCodePrint(content,line,true));
390                                    struct.set("codePrintPlain",getCodePrint(content,line,false));
391                            }
392                            tagContext.append(struct);
393                    } 
394                    catch (Exception e) {}
395            }
396            
397            private static String getCodePrint(String[] content,int line, boolean asHTML ) {
398                    StringBuffer sb=new StringBuffer();
399                    // bad Line
400                    for(int i=line-2;i<line+3;i++) {
401                            if(i>0 && i<=content.length) {
402                                    if(asHTML && i==line)sb.append("<b>");
403                                    if(asHTML)sb.append(i+": "+StringUtil.escapeHTML(content[i-1]));
404                                    else sb.append(i+": "+(content[i-1]));
405                                    if(asHTML && i==line)sb.append("</b>");
406                                    if(asHTML)sb.append("<br>");
407                                    sb.append('\n');
408                            }
409                    }
410                    return sb.toString();
411            }
412            
413            /**
414             * @see railo.runtime.dump.Dumpable#toDumpData(railo.runtime.PageContext, int)
415             */
416            public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) {
417                    
418                    //FFFFCF
419            DumpTable htmlBox = new DumpTablePro("exception","#ff9900","#FFCC00","#000000");
420                    htmlBox.setTitle("Railo ["+Info.getVersionAsString()+"] - Error ("+StringUtil.ucFirst(getTypeAsString())+")");
421                    
422                    
423                    // Message
424                    htmlBox.appendRow(1,new SimpleDumpData("Message"),new SimpleDumpData(getMessage()));
425                    
426                    // Detail
427                    String detail=getDetail();
428                    if(!StringUtil.isEmpty(detail,true))
429                            htmlBox.appendRow(1,new SimpleDumpData("Detail"),new SimpleDumpData(detail));
430                    
431                    // additional
432                    Iterator it=additional.keyIterator();
433                    while(it.hasNext()) {
434                            String key=it.next().toString();
435                            htmlBox.appendRow(1,new SimpleDumpData(key),new SimpleDumpData(additional.get(key,"").toString()));
436                    }
437                    
438                    Array tagContext = getTagContext(pageContext.getConfig());
439                    // Context MUSTMUST
440                    if(tagContext.size()>0) {
441                            Collection.Key[] keys=tagContext.keys();
442                            DumpTable context=new DumpTable("#ff9900","#FFCC00","#000000");
443                            //context.setTitle("The Error Occurred in");
444                            //context.appendRow(0,new SimpleDumpData("The Error Occurred in"));
445                            context.appendRow(7,
446                                            new SimpleDumpData(""),
447                                            new SimpleDumpData("template"),
448                                            new SimpleDumpData("line"));
449                            try {
450                                    for(int i=0;i<keys.length;i++) {
451                                            Struct struct=(Struct)tagContext.get(keys[i],null);
452                                            context.appendRow(1,
453                                                            new SimpleDumpData(i>0?"called from ":"occurred in"),
454                                                            new SimpleDumpData(struct.get("template","")+""),
455                                                            new SimpleDumpData(Caster.toString(struct.get("line",null))));
456                                            
457                                            
458                                    }
459                                    htmlBox.appendRow(1,new SimpleDumpData("Context"),context);
460                                    
461                                    
462                                    // Code
463                                    String strCode=((Struct)tagContext.get(1,null)).get("codePrintPlain","").toString();
464                                    String[] arrCode = List.listToStringArray(strCode, '\n');
465                                    arrCode=List.trim(arrCode);
466                                    DumpTable code=new DumpTable("#ff9900","#FFCC00","#000000");
467                                    
468                                    for(int i=0;i<arrCode.length;i++) {
469                                            code.appendRow(i==2?1:0,new SimpleDumpData(arrCode[i]));
470                                    }
471                                    htmlBox.appendRow(1,new SimpleDumpData("Code"),code);
472    
473                            } 
474                catch (PageException e) {}
475                    }
476                    
477                    
478                    // Java Stacktrace
479                    String strST=getStackTraceAsString();
480                    String[] arrST = List.listToStringArray(strST, '\n');
481                    arrST=List.trim(arrST);
482                    DumpTable st=new DumpTable("#ff9900","#FFCC00","#000000");
483                    
484                    for(int i=0;i<arrST.length;i++) {
485                            st.appendRow(i==0?1:0,new SimpleDumpData(arrST[i]));
486                    }
487                    htmlBox.appendRow(1,new SimpleDumpData("Java Stacktrace"),st);
488    
489                    return htmlBox; 
490            }       
491            
492            /**
493         * @see railo.runtime.exp.PageException#getStackTraceAsString()
494         */
495            public String getStackTraceAsString() {
496                    
497            StringWriter sw=new StringWriter();
498                PrintWriter pw=new PrintWriter(sw);
499            printStackTrace(pw);
500            pw.flush();
501            return sw.toString();
502        }
503        
504        
505        
506        /**
507         * @see railo.runtime.exp.PageException#printStackTrace()
508         */
509        public void printStackTrace() {
510            printStackTrace(System.err);
511        }
512        
513        /**
514         * @see railo.runtime.exp.PageException#printStackTrace(java.io.PrintStream)
515         */
516        public void printStackTrace(PrintStream s) {
517            StackTraceElement[] traces = getStackTraceElements(this);
518            StackTraceElement trace;
519            
520            s.println(getMessage());
521            for(int i=0;i<traces.length;i++){
522                trace=traces[i];
523                s.println("\tat "+trace);
524            }
525        }
526        
527        /**
528         * @see railo.runtime.exp.PageException#printStackTrace(java.io.PrintWriter)
529         */
530        public void printStackTrace(PrintWriter s) {
531            StackTraceElement[] traces = getStackTraceElements(this);
532            StackTraceElement trace;
533            
534            s.println(getMessage());
535            for(int i=0;i<traces.length;i++){
536                trace=traces[i];
537                s.println("\tat "+trace+":"+trace.getLineNumber());
538            }
539        }
540        
541    
542        private static StackTraceElement[] getStackTraceElements(Throwable t) {
543            StackTraceElement[] st=getStackTraceElements(t,true);
544            if(st==null) st= getStackTraceElements(t,false);
545            return st;
546        }
547        
548        private static StackTraceElement[] getStackTraceElements(Throwable t, boolean onlyWithCML) {
549            StackTraceElement[] st;
550            Throwable cause=t.getCause();
551            if(cause!=null){
552                    st = getStackTraceElements(cause,onlyWithCML);
553                    if(st!=null) return st;
554            }
555            
556            st=t.getStackTrace();
557            if(!onlyWithCML || hasCFMLinStacktrace(st)){
558                    return st;
559            }
560            return null;
561            }
562        
563    
564        private static boolean hasCFMLinStacktrace(StackTraceElement[] traces) {
565                    for(int i=0;i<traces.length;i++) {
566                            if(traces[i].getFileName()!=null && !traces[i].getFileName().endsWith(".java")) return true;
567                    }
568                    return false;
569            }
570        /*ths code has produced duplettes
571         * private static void fillStackTraceElements(ArrayList<StackTraceElement> causes, Throwable t) {
572                    if(t==null) return;
573                    fillStackTraceElements(causes, t.getCause());
574                    StackTraceElement[] traces = t.getStackTrace();
575                    for(int i=0;i<traces.length;i++) {
576                            //if(causes.contains(traces[i]))
577                            causes.add(traces[i]);
578                    }
579            }*/
580        
581            /**
582             * set a additional key value
583             * @param key
584             * @param value
585             */
586            public void setAdditional(String key, Object value) {
587                    additional.setEL(KeyImpl.getInstance(key),StringUtil.toStringEmptyIfNull(value));
588            }
589            
590            
591            /**
592         * @see railo.runtime.exp.PageException#getRootCause()
593         */
594            public Throwable getRootCause() {
595            Throwable cause=this; 
596            Throwable temp; 
597            
598            while((temp=cause.getCause())!=null)cause=temp;
599            return cause;
600            }
601    
602            /**
603         * @see railo.runtime.exp.PageException#getTracePointer()
604         */
605            public int getTracePointer() {
606                    return tracePointer;
607            }
608            /**
609         * @see railo.runtime.exp.PageException#setTracePointer(int)
610         */
611            public void setTracePointer(int tracePointer) {
612                    this.tracePointer = tracePointer;
613            }
614            
615            /* *
616         * @see railo.runtime.exp.PageException#typeEqual(java.lang.String)
617         *  /
618            public final boolean typeEqual(String type) {
619                type=type.toLowerCase().trim();
620                print.ln(getTypeAsString()+"-"+type);
621                    // ANY
622            if(type.equals("any")) return true;
623                                    
624                    // translate customtype ->custom_type
625                    else if(type.equals("customtype")) return typeEqual("custom_type");
626                    
627            // Tye Compare
628                    else if(getTypeAsString().equalsIgnoreCase(type)) return true;
629                    
630            // Custom Type
631                    else if(getTypeAsString().equals("custom_type")) {
632                        return compareCustomType(type,getCustomTypeAsString().toLowerCase().trim());
633                    }
634            // Native Compare
635            
636                    return false;           
637            }*/
638        
639        /**
640         * @see railo.runtime.exp.IPageException#typeEqual(java.lang.String)
641         */
642        public boolean typeEqual(String type) {
643            if(type==null) return true;
644            type=StringUtil.toUpperCase(type);
645            // ANY
646            if(type.equals("ANY")) return true;// MUST check
647            // Type Compare
648            if(getTypeAsString().equalsIgnoreCase(type)) return true;
649            return getClass().getName().equalsIgnoreCase(type);
650        }
651        
652        /**
653         * @see railo.runtime.exp.PageException#getTypeAsString()
654         */
655            public String getTypeAsString() {
656                    return type;
657            }
658            
659            /**
660         * @see railo.runtime.exp.PageException#getCustomTypeAsString()
661         */
662            public String getCustomTypeAsString() {
663                    return customType==null?type:customType;
664            }
665        
666        /**
667         * @see railo.runtime.exp.PageException#getAdditional()
668         */
669            public Struct getAdditional() {
670            return additional;
671        }public Struct getAddional() {
672            return additional;
673        }
674        
675        /**
676         * @see java.lang.Throwable#getStackTrace()
677         */
678        public StackTraceElement[] getStackTrace() {
679            return super.getStackTrace();
680        }
681        
682        /*public static void printStackTrace(PrintWriter s,Throwable t) {
683            
684            //while((temp=cause.getCause())!=null)cause=temp;
685            
686            StackTraceElement[] traces = t.getStackTrace();
687            StackTraceElement trace;
688            
689            s.println(t.getMessage());
690            for(int i=0;i<traces.length;i++){
691                trace=traces[i];
692                s.println("\tat "+trace+":"+trace.getLineNumber());
693            }
694            t=t.getCause();
695            if(t!=null)printStackTrace(s,t);
696        }*/
697        
698        
699        
700    }