【优化】更加优雅地打印配置加载错误。默认不再显示大段的堆栈信息
parent
54685289af
commit
df722abb4a
|
|
@ -262,6 +262,10 @@ Options:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s_logger.Error("GenJob fail. err:{err} msg:{msg}", res.ErrCode, res.ErrMsg);
|
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;
|
return 1;
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,6 @@ namespace Luban.Common
|
||||||
READ_FILE_FAIL,
|
READ_FILE_FAIL,
|
||||||
JOB_ARGUMENT_ERROR,
|
JOB_ARGUMENT_ERROR,
|
||||||
JOB_EXCEPTION,
|
JOB_EXCEPTION,
|
||||||
|
DATA_PARSE_ERROR,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,8 @@ namespace Luban.Common.Protos
|
||||||
|
|
||||||
public List<FileInfo> ScatteredFiles { get; set; } = new List<FileInfo>();
|
public List<FileInfo> ScatteredFiles { get; set; } = new List<FileInfo>();
|
||||||
|
|
||||||
|
public string StackTrace { get; set; }
|
||||||
|
|
||||||
public override int GetTypeId()
|
public override int GetTypeId()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -81,6 +83,7 @@ namespace Luban.Common.Protos
|
||||||
os.WriteString(ErrMsg);
|
os.WriteString(ErrMsg);
|
||||||
Bright.Common.SerializationUtil.Serialize(os, FileGroups);
|
Bright.Common.SerializationUtil.Serialize(os, FileGroups);
|
||||||
Bright.Common.SerializationUtil.Serialize(os, ScatteredFiles);
|
Bright.Common.SerializationUtil.Serialize(os, ScatteredFiles);
|
||||||
|
os.WriteString(StackTrace);
|
||||||
}
|
}
|
||||||
public override void Deserialize(ByteBuf os)
|
public override void Deserialize(ByteBuf os)
|
||||||
{
|
{
|
||||||
|
|
@ -88,6 +91,7 @@ namespace Luban.Common.Protos
|
||||||
ErrMsg = os.ReadString();
|
ErrMsg = os.ReadString();
|
||||||
Bright.Common.SerializationUtil.Deserialize(os, FileGroups);
|
Bright.Common.SerializationUtil.Deserialize(os, FileGroups);
|
||||||
Bright.Common.SerializationUtil.Deserialize(os, ScatteredFiles);
|
Bright.Common.SerializationUtil.Deserialize(os, ScatteredFiles);
|
||||||
|
StackTrace = os.ReadString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -336,9 +336,16 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
list.Add(f.CType.Apply(this, f.Remapper, new ExcelStream(stream.ReadCell(), sep, false), ass));
|
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)
|
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;
|
return list;
|
||||||
|
|
|
||||||
|
|
@ -128,9 +128,16 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
list.Add(f.CType.Apply(this, row.GetSubTitleNamedRow(fname), f.IsMultiRow /* 肯定是 false */, f.IsNullable));
|
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)
|
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
|
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));
|
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)
|
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
|
else
|
||||||
|
|
@ -166,9 +180,16 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
{
|
{
|
||||||
list.Add(f.CType.Apply(ExcelDataCreator.Ins, f.Remapper, stream, (DefAssembly)bean.AssemblyBase));
|
list.Add(f.CType.Apply(ExcelDataCreator.Ins, f.Remapper, stream, (DefAssembly)bean.AssemblyBase));
|
||||||
}
|
}
|
||||||
|
catch (DataCreateException dce)
|
||||||
|
{
|
||||||
|
dce.Push(bean, f);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
catch (Exception e)
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -130,40 +130,47 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
}
|
}
|
||||||
|
|
||||||
var fields = new List<DType>();
|
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 (ele.ValueKind == JsonValueKind.Null || ele.ValueKind == JsonValueKind.Undefined)
|
||||||
{
|
{
|
||||||
if (field.CType.IsNullable)
|
if (f.CType.IsNullable)
|
||||||
{
|
{
|
||||||
fields.Add(null);
|
fields.Add(null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new Exception($"结构:{implBean.FullName} 字段:{field.Name} 不能 null or undefined ");
|
throw new Exception($"结构:{implBean.FullName} 字段:{f.Name} 不能 null or undefined ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
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)
|
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);
|
fields.Add(null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new Exception($"结构:{implBean.FullName} 字段:{field.Name} 缺失");
|
throw new Exception($"结构:{implBean.FullName} 字段:{f.Name} 缺失");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new DBean(bean, implBean, fields);
|
return new DBean(bean, implBean, fields);
|
||||||
|
|
|
||||||
|
|
@ -172,29 +172,36 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
}
|
}
|
||||||
|
|
||||||
var fields = new List<DType>();
|
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)
|
if (ele != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Console.WriteLine("field:{0} type:{1} value:{2}", field.Name, ele.GetType(), ele);
|
// 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)
|
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);
|
fields.Add(null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new Exception($"结构:{implBean.FullName} 字段:{field.Name} 缺失");
|
throw new Exception($"结构:{implBean.FullName} 字段:{f.Name} 缺失");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new DBean(bean, implBean, fields);
|
return new DBean(bean, implBean, fields);
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,8 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
throw new Exception($"位置:{stream.CurrentExcelPosition} 出错 ==> {e.Message}", e);
|
var dce = new DataCreateException(e, stream.CurrentExcelPosition);
|
||||||
|
throw dce;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
|
|
@ -132,7 +133,8 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
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);
|
return new DMap(type, map);
|
||||||
|
|
|
||||||
|
|
@ -114,26 +114,33 @@ namespace Luban.Job.Cfg.DataCreators
|
||||||
}
|
}
|
||||||
|
|
||||||
var fields = new List<DType>();
|
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();
|
XElement fele = feles.FirstOrDefault();
|
||||||
if (fele == null)
|
if (fele == null)
|
||||||
{
|
{
|
||||||
if (field.CType.IsNullable)
|
if (f.CType.IsNullable)
|
||||||
{
|
{
|
||||||
fields.Add(null);
|
fields.Add(null);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
throw new Exception($"字段:{field.Name} 缺失");
|
throw new Exception($"字段:{f.Name} 缺失");
|
||||||
}
|
}
|
||||||
try
|
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)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
throw new Exception($"结构:{implBean.FullName} 字段:{field.Name} 读取失败 => {e.Message}", e);
|
var dce = new DataCreateException(e, "");
|
||||||
|
dce.Push(bean, f);
|
||||||
|
throw dce;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Luban.Job.Cfg.DataCreators;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
|
|
@ -25,6 +26,10 @@ namespace Luban.Job.Cfg.DataSources
|
||||||
source.Load(url, sheetName, stream, exportTestData);
|
source.Load(url, sheetName, stream, exportTestData);
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
catch (DataCreateException dce)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
throw new Exception($"文件{url} 加载失败 ==> {e.Message}", e);
|
throw new Exception($"文件{url} 加载失败 ==> {e.Message}", e);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using ExcelDataReader;
|
using ExcelDataReader;
|
||||||
|
using Luban.Job.Cfg.DataCreators;
|
||||||
using Luban.Job.Cfg.Datas;
|
using Luban.Job.Cfg.Datas;
|
||||||
using Luban.Job.Cfg.Defs;
|
using Luban.Job.Cfg.Defs;
|
||||||
using Luban.Job.Common.Types;
|
using Luban.Job.Common.Types;
|
||||||
|
|
@ -66,6 +67,11 @@ namespace Luban.Job.Cfg.DataSources.Excel
|
||||||
{
|
{
|
||||||
datas.AddRange(sheet.ReadMulti(type, ((DefBean)type.Bean).IsMultiRow));
|
datas.AddRange(sheet.ReadMulti(type, ((DefBean)type.Bean).IsMultiRow));
|
||||||
}
|
}
|
||||||
|
catch (DataCreateException dce)
|
||||||
|
{
|
||||||
|
dce.OriginDataLocation = sheet.RawUrl;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
throw new Exception($"sheet:{sheet.Name} ==> {e.Message} {e.StackTrace}", e);
|
throw new Exception($"sheet:{sheet.Name} ==> {e.Message} {e.StackTrace}", e);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ using Bright.Time;
|
||||||
using CommandLine;
|
using CommandLine;
|
||||||
using Luban.Common.Protos;
|
using Luban.Common.Protos;
|
||||||
using Luban.Common.Utils;
|
using Luban.Common.Utils;
|
||||||
|
using Luban.Job.Cfg.DataCreators;
|
||||||
using Luban.Job.Cfg.Defs;
|
using Luban.Job.Cfg.Defs;
|
||||||
using Luban.Job.Cfg.Generate;
|
using Luban.Job.Cfg.Generate;
|
||||||
using Luban.Job.Cfg.RawDefs;
|
using Luban.Job.Cfg.RawDefs;
|
||||||
|
|
@ -424,6 +425,17 @@ namespace Luban.Job.Cfg
|
||||||
res.ScatteredFiles.AddRange(genScatteredFiles);
|
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)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
res.ErrCode = Luban.Common.EErrorCode.JOB_EXCEPTION;
|
res.ErrCode = Luban.Common.EErrorCode.JOB_EXCEPTION;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using Bright.Time;
|
using Bright.Time;
|
||||||
using Luban.Common.Utils;
|
using Luban.Common.Utils;
|
||||||
using Luban.Job.Cfg.Cache;
|
using Luban.Job.Cfg.Cache;
|
||||||
|
using Luban.Job.Cfg.DataCreators;
|
||||||
using Luban.Job.Cfg.Datas;
|
using Luban.Job.Cfg.Datas;
|
||||||
using Luban.Job.Cfg.DataSources;
|
using Luban.Job.Cfg.DataSources;
|
||||||
using Luban.Job.Cfg.Defs;
|
using Luban.Job.Cfg.Defs;
|
||||||
|
|
@ -186,6 +187,14 @@ namespace Luban.Job.Cfg.Utils
|
||||||
return record != null ? new List<Record> { record } : new List<Record>();
|
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)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
throw new Exception($"配置文件:{originFile} 生成失败. ==> {e.Message}", e);
|
throw new Exception($"配置文件:{originFile} 生成失败. ==> {e.Message}", e);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue