You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gnosygnu_xowa/100_core/src_000_err/gplx/ErrMsgWtr.java

113 lines
4.4 KiB

/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx;
import gplx.core.strings.*;
public class ErrMsgWtr {
public String Message_gplx(Exception thrown) {
Err err = Err.convert_(thrown); // convert thrown to Err to make rest of class easier
Err[] innerAry = InnerAsAry(err);
String_bldr sb = String_bldr_.new_();
WriteError(innerAry, sb, 0);
WriteInner(innerAry, sb);
WriteStack(innerAry, sb);
return sb.XtoStr();
}
public String Message_gplx_brief(Exception thrown) {
Err err = Err.convert_(thrown); // convert thrown to Err to make rest of proc easier
String_bldr sb = String_bldr_.new_();
sb.Add(err.Hdr());
if (err.Args().Count() > 0) sb.Add(" --");
for (Object kvo : err.Args()) {
KeyVal kv = (KeyVal)kvo;
String key = kv.Key(), val = kv.Val_to_str_or_empty();
sb.Add_fmt(" {0}='{1}'", key, val);
}
sb.Add_fmt(" [{0}]", err.Key());
return sb.XtoStr();
}
void WriteInner(Err[] errAry, String_bldr sb) {
int len = Array_.Len(errAry); if (len <= 1) return; // no inners; return;
for (int i = 1; i < len; i++)
WriteError(errAry, sb, i);
}
void WriteError(Err[] errAry, String_bldr sb, int i) {
Err err = errAry[i];
String msg = err.Hdr();
String typ = String_.Eq(err.Key(), "") ? "" : String_.Concat(" <", err.Key(), ">");
boolean onlyOne = errAry.length == 1;
String idxStr = onlyOne ? "" : Int_.Xto_str(i);
sb.Add(idxStr).Add("\t").Add(msg).Add(typ).Add_char_crlf(); // ex: " @count must be > 0 <gplx.arg>"
WriteKeyValAry(sb, err.Args());
sb.Add("\t").Add(err.Proc().SignatureRaw()).Add_char_crlf();
// WriteKeyValAry(sb, err.ProcArgs());
}
void WriteKeyValAry(String_bldr sb, List_adp ary) {
// calc keyMax for valIndentLen
int keyMax = 0;
for (Object o : ary) {
KeyVal kv = (KeyVal)o;
int keyLen = String_.Len(kv.Key());
if (keyLen > keyMax) keyMax = keyLen + 1; // +1 to guarantee one space between key and val
}
if (keyMax < 8)keyMax = 8; // separate by at least 8 chars
for (Object o : ary) {
KeyVal kv = (KeyVal)o;
String key = kv.Key(); int keyLen = String_.Len(key);
String valIndent = String_.Repeat(" ", keyMax - keyLen);
sb.Add("\t\t@").Add(key).Add(valIndent).Add(kv.Val_to_str_or_empty()).Add_char_crlf();
}
}
void WriteStack(Err[] errAry, String_bldr sb) {
if (Env_.Mode_testing()) return; // only write stack when not testing
int len = Array_.Len(errAry); if (len == 0) return; // shouldn't happen, but don't want to throw err
Err first = errAry[0];
boolean onlyOne = len == 1;
sb.Add_str_w_crlf(String_.Repeat("-", 80));
List_adp tmp = List_adp_.new_();
Ordered_hash callStack = first.CallStack(); int callStackCount = callStack.Count();
for (int i = 0; i < callStackCount ; i++) {
ErrProcData proc = (ErrProcData)callStack.Get_at(i);
// get procIndex
int idx = -1;
for (int j = 0; j < len; j++) {
ErrProcData comp = errAry[j].Proc();
if (String_.Eq(proc.Raw(), comp.Raw())) {idx = j; break;}
}
String idxStr = onlyOne ? "" : Int_.Xto_str(idx);
String hdr = idx == -1 ? "\t" : idxStr + "\t";
String ideAddressSpr = String_.CrLf + "\t\t";
String ideAddress = String_.Eq(proc.IdeAddress(), "") ? "" : ideAddressSpr + proc.IdeAddress(); // NOTE: ideAddress will be blank in compiled mode
String msg = String_.Concat(hdr, proc.SignatureRaw(), ideAddress);
tmp.Add(msg);
}
tmp.Reverse();
for (Object o : tmp)
sb.Add_str_w_crlf((String)o);
}
static Err[] InnerAsAry(Err err) {
List_adp errAry = List_adp_.new_();
Err cur = Err_.as_(err);
while (cur != null) {
errAry.Add(cur);
cur = cur.Inner();
}
return (Err[])errAry.To_ary(Err.class);
}
public static final ErrMsgWtr _ = new ErrMsgWtr(); ErrMsgWtr() {}
}