【优化】更加优雅地打印配置加载错误。默认不再显示大段的堆栈信息

main
walon 2021-07-29 18:14:15 +08:00
parent 54685289af
commit df722abb4a
14 changed files with 162 additions and 26 deletions

View File

@ -262,6 +262,10 @@ Options:
else
{
s_logger.Error("GenJob fail. err:{err} msg:{msg}", res.ErrCode, res.ErrMsg);
if (!string.IsNullOrEmpty(res.StackTrace))
{
s_logger.Debug("StackTrace: {}", res.StackTrace);
}
}
return 1;

View File

@ -8,5 +8,6 @@ namespace Luban.Common
READ_FILE_FAIL,
JOB_ARGUMENT_ERROR,
JOB_EXCEPTION,
DATA_PARSE_ERROR,
}
}

View File

@ -70,6 +70,8 @@ namespace Luban.Common.Protos
public List<FileInfo> ScatteredFiles { get; set; } = new List<FileInfo>();
public string StackTrace { get; set; }
public override int GetTypeId()
{
return 0;
@ -81,6 +83,7 @@ namespace Luban.Common.Protos
os.WriteString(ErrMsg);
Bright.Common.SerializationUtil.Serialize(os, FileGroups);
Bright.Common.SerializationUtil.Serialize(os, ScatteredFiles);
os.WriteString(StackTrace);
}
public override void Deserialize(ByteBuf os)
{
@ -88,6 +91,7 @@ namespace Luban.Common.Protos
ErrMsg = os.ReadString();
Bright.Common.SerializationUtil.Deserialize(os, FileGroups);
Bright.Common.SerializationUtil.Deserialize(os, ScatteredFiles);
StackTrace = os.ReadString();
}
}

View File

@ -0,0 +1,44 @@
using Luban.Job.Cfg.Defs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.DataCreators
{
public class DataCreateException : System.Exception
{
private List<(DefBean, DefField)> VariablePath { get; } = new();
public string OriginDataLocation { get; set; }
public string DataLocationInFile { get; }
public string OriginErrorMsg { get; }
public string OriginStackTrace { get; }
public DataCreateException(Exception e, string dataLocation) : base("DataCreateException", e)
{
this.OriginStackTrace = e.StackTrace;
this.OriginErrorMsg = e.Message;
this.DataLocationInFile = dataLocation;
}
public void Push(DefBean bean, DefField f)
{
VariablePath.Add((bean, f));
}
public string VariableFullPathStr
{
get
{
var path = new List<(DefBean, DefField)>(VariablePath);
path.Reverse();
return string.Join(" => ", path.Select(b => $"{{{b.Item1.FullName}}}.{b.Item2.Name}"));
}
}
}
}

View File

@ -336,9 +336,16 @@ namespace Luban.Job.Cfg.DataCreators
list.Add(f.CType.Apply(this, f.Remapper, new ExcelStream(stream.ReadCell(), sep, false), ass));
}
}
catch (DataCreateException dce)
{
dce.Push(bean, f);
throw;
}
catch (Exception e)
{
throw new InvalidExcelDataException($"读取结构:{bean.FullName} 字段:{f.Name} 出错 ==> {e.Message}", e);
var dce = new DataCreateException(e, stream.CurrentExcelPosition);
dce.Push(bean, f);
throw dce;
}
}
return list;

View File

@ -128,9 +128,16 @@ namespace Luban.Job.Cfg.DataCreators
list.Add(f.CType.Apply(this, row.GetSubTitleNamedRow(fname), f.IsMultiRow /* 肯定是 false */, f.IsNullable));
}
}
catch (DataCreateException dce)
{
dce.Push(bean, f);
throw;
}
catch (Exception e)
{
throw new Exception($"读取结构:{bean.FullName} 字段:{fname} 读取 出错 ==> {e.Message}", e);
var dce = new DataCreateException(e, $"列:{fname}");
dce.Push(bean, f);
throw dce;
}
}
else
@ -154,9 +161,16 @@ namespace Luban.Job.Cfg.DataCreators
list.Add(f.CType.Apply(ExcelDataCreator.Ins, null, row.GetMultiRowStream(f.Name, sep), (DefAssembly)bean.AssemblyBase));
}
}
catch (DataCreateException dce)
{
dce.Push(bean, f);
throw;
}
catch (Exception e)
{
throw new Exception($"读取结构:{bean.FullName} 多行字段:{f.Name} 读取 出错 ==> {e.Message}", e);
var dce = new DataCreateException(e, "");
dce.Push(bean, f);
throw dce;
}
}
else
@ -166,9 +180,16 @@ namespace Luban.Job.Cfg.DataCreators
{
list.Add(f.CType.Apply(ExcelDataCreator.Ins, f.Remapper, stream, (DefAssembly)bean.AssemblyBase));
}
catch (DataCreateException dce)
{
dce.Push(bean, f);
throw;
}
catch (Exception e)
{
throw new Exception($"读取结构:{bean.FullName} 字段:{f.Name} 位置:{stream.CurrentExcelPosition} 出错 ==> {e.Message}", e);
var dce = new DataCreateException(e, stream.CurrentExcelPosition);
dce.Push(bean, f);
throw dce;
}
}
}

View File

@ -130,40 +130,47 @@ namespace Luban.Job.Cfg.DataCreators
}
var fields = new List<DType>();
foreach (var field in implBean.HierarchyFields)
foreach (DefField f in implBean.HierarchyFields)
{
if (x.TryGetProperty(field.Name, out var ele))
if (x.TryGetProperty(f.Name, out var ele))
{
if (ele.ValueKind == JsonValueKind.Null || ele.ValueKind == JsonValueKind.Undefined)
{
if (field.CType.IsNullable)
if (f.CType.IsNullable)
{
fields.Add(null);
}
else
{
throw new Exception($"结构:{implBean.FullName} 字段:{field.Name} 不能 null or undefined ");
throw new Exception($"结构:{implBean.FullName} 字段:{f.Name} 不能 null or undefined ");
}
}
else
{
try
{
fields.Add(field.CType.Apply(this, ele, ass));
fields.Add(f.CType.Apply(this, ele, ass));
}
catch (DataCreateException dce)
{
dce.Push(bean, f);
throw;
}
catch (Exception e)
{
throw new Exception($"结构:{implBean.FullName} 字段:{field.Name} 读取失败 => {e.Message}", e);
var dce = new DataCreateException(e, "");
dce.Push(bean, f);
throw dce;
}
}
}
else if (field.CType.IsNullable)
else if (f.CType.IsNullable)
{
fields.Add(null);
}
else
{
throw new Exception($"结构:{implBean.FullName} 字段:{field.Name} 缺失");
throw new Exception($"结构:{implBean.FullName} 字段:{f.Name} 缺失");
}
}
return new DBean(bean, implBean, fields);

View File

@ -172,29 +172,36 @@ namespace Luban.Job.Cfg.DataCreators
}
var fields = new List<DType>();
foreach (var field in implBean.HierarchyFields)
foreach (DefField f in implBean.HierarchyFields)
{
var ele = table[field.Name];
var ele = table[f.Name];
if (ele != null)
{
try
{
// Console.WriteLine("field:{0} type:{1} value:{2}", field.Name, ele.GetType(), ele);
fields.Add(field.CType.Apply(this, ele, ass));
fields.Add(f.CType.Apply(this, ele, ass));
}
catch (DataCreateException dce)
{
dce.Push(implBean, f);
throw;
}
catch (Exception e)
{
throw new Exception($"结构:{implBean.FullName} 字段:{field.Name} 读取失败 => {e.Message}", e);
var dce = new DataCreateException(e, "");
dce.Push(bean, f);
throw dce;
}
}
else if (field.CType.IsNullable)
else if (f.CType.IsNullable)
{
fields.Add(null);
}
else
{
throw new Exception($"结构:{implBean.FullName} 字段:{field.Name} 缺失");
throw new Exception($"结构:{implBean.FullName} 字段:{f.Name} 缺失");
}
}
return new DBean(bean, implBean, fields);

View File

@ -98,7 +98,8 @@ namespace Luban.Job.Cfg.DataCreators
}
catch (Exception e)
{
throw new Exception($"位置:{stream.CurrentExcelPosition} 出错 ==> {e.Message}", e);
var dce = new DataCreateException(e, stream.CurrentExcelPosition);
throw dce;
}
}
return list;
@ -132,7 +133,8 @@ namespace Luban.Job.Cfg.DataCreators
}
catch (Exception e)
{
throw new Exception($"位置:{stream.CurrentExcelPosition} 出错 ==> {e.Message}", e);
var dce = new DataCreateException(e, stream.CurrentExcelPosition);
throw dce;
}
}
return new DMap(type, map);

View File

@ -114,26 +114,33 @@ namespace Luban.Job.Cfg.DataCreators
}
var fields = new List<DType>();
foreach (var field in implBean.HierarchyFields)
foreach (DefField f in implBean.HierarchyFields)
{
var feles = x.Elements(field.Name);
var feles = x.Elements(f.Name);
XElement fele = feles.FirstOrDefault();
if (fele == null)
{
if (field.CType.IsNullable)
if (f.CType.IsNullable)
{
fields.Add(null);
continue;
}
throw new Exception($"字段:{field.Name} 缺失");
throw new Exception($"字段:{f.Name} 缺失");
}
try
{
fields.Add(field.CType.Apply(this, fele, ass));
fields.Add(f.CType.Apply(this, fele, ass));
}
catch (DataCreateException dce)
{
dce.Push(implBean, f);
throw;
}
catch (Exception e)
{
throw new Exception($"结构:{implBean.FullName} 字段:{field.Name} 读取失败 => {e.Message}", e);
var dce = new DataCreateException(e, "");
dce.Push(bean, f);
throw dce;
}
}

View File

@ -1,3 +1,4 @@
using Luban.Job.Cfg.DataCreators;
using System;
using System.IO;
@ -25,6 +26,10 @@ namespace Luban.Job.Cfg.DataSources
source.Load(url, sheetName, stream, exportTestData);
return source;
}
catch (DataCreateException dce)
{
throw;
}
catch (Exception e)
{
throw new Exception($"文件{url} 加载失败 ==> {e.Message}", e);

View File

@ -1,4 +1,5 @@
using ExcelDataReader;
using Luban.Job.Cfg.DataCreators;
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.Defs;
using Luban.Job.Common.Types;
@ -66,6 +67,11 @@ namespace Luban.Job.Cfg.DataSources.Excel
{
datas.AddRange(sheet.ReadMulti(type, ((DefBean)type.Bean).IsMultiRow));
}
catch (DataCreateException dce)
{
dce.OriginDataLocation = sheet.RawUrl;
throw;
}
catch (Exception e)
{
throw new Exception($"sheet:{sheet.Name} ==> {e.Message} {e.StackTrace}", e);

View File

@ -2,6 +2,7 @@ using Bright.Time;
using CommandLine;
using Luban.Common.Protos;
using Luban.Common.Utils;
using Luban.Job.Cfg.DataCreators;
using Luban.Job.Cfg.Defs;
using Luban.Job.Cfg.Generate;
using Luban.Job.Cfg.RawDefs;
@ -424,6 +425,17 @@ namespace Luban.Job.Cfg
res.ScatteredFiles.AddRange(genScatteredFiles);
}
}
catch (DataCreateException e)
{
res.ErrCode = Luban.Common.EErrorCode.DATA_PARSE_ERROR;
res.ErrMsg = $@"加载数据失败.
: {e.OriginDataLocation}
: {e.DataLocationInFile}
Err: {e.OriginErrorMsg}
: {e.VariableFullPathStr}
";
res.StackTrace = e.OriginStackTrace;
}
catch (Exception e)
{
res.ErrCode = Luban.Common.EErrorCode.JOB_EXCEPTION;

View File

@ -1,6 +1,7 @@
using Bright.Time;
using Luban.Common.Utils;
using Luban.Job.Cfg.Cache;
using Luban.Job.Cfg.DataCreators;
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.DataSources;
using Luban.Job.Cfg.Defs;
@ -186,6 +187,14 @@ namespace Luban.Job.Cfg.Utils
return record != null ? new List<Record> { record } : new List<Record>();
}
}
catch (DataCreateException dce)
{
if (string.IsNullOrWhiteSpace(dce.OriginDataLocation))
{
dce.OriginDataLocation = originFile;
}
throw;
}
catch (Exception e)
{
throw new Exception($"配置文件:{originFile} 生成失败. ==> {e.Message}", e);