d更好异常

网友投稿 257 2022-11-05


d更好异常

​​原文​​

module arsd.exception;interface ThrowableBase { void fly(string file = __FILE__, size_t line = __LINE__); //应该内置在编译器的throw语句中 // 需要时覆盖 void printMembers(scope void delegate(in char[]) sink) const; // 用mixin PrintMembers;插件 void getHumanReadableMessage(scope void delegate(in char[]) sink) const;//可读信息 void printName(scope void delegate(in char[]) sink) const; // 不喜欢rtti时 // 准备好时就调用它 void toString(scope void delegate(in char[]) sink) const;}mixin template ThrowableBaseImplementation() { // 在抛出点而不是在 ctor 中,设置文件和行 // 从而分开分配与错误信息 // 将设置file+line,从而简化重用. void fly(string file = __FILE__, size_t line = __LINE__) { this.file = file; this.line = line; throw this; } /* virtual */ void getHumanReadableMessage(scope void delegate(in char[]) sink) const { sink(msg); // 兼容 } // 打印真正有用的信息 // 用下面插件 /* virtual */ void printMembers(scope void delegate(in char[]) sink) const { // 插件 } /* virtual */ void printName(scope void delegate(in char[]) sink) const { sink(typeid(this).name); } override void toString(scope void delegate(in char[]) sink) const { char[32] tmpBuff = void; printName(sink); sink("@"); sink(file); sink("("); sink(line.sizeToTempString(tmpBuff[])); sink(")"); sink(": "); getHumanReadableMessage(sink); sink("\n"); printMembers(sink); if (info) { try { sink("----------------"); foreach (t; info) { sink("\n"); sink(t); } } catch (Throwable) { // 忽略 } } }}class ExceptionBase : Exception, ThrowableBase { // 大大简化 this() { super(""); } mixin ThrowableBaseImplementation;}class ErrorBase : Error, ThrowableBase { this() { super(""); } mixin ThrowableBaseImplementation;}// 派生类中来自动打印`所有成员`以方便调试的插件mixin template PrintMembers() { override void printMembers(scope void delegate(in char[]) sink) const { foreach(memberName; __traits(derivedMembers, typeof(this))) { static if(is(typeof(__traits(getMember, this, memberName))) && !is(typeof(__traits(getMember, typeof(this), memberName)) == function)) { sink("\t"); sink(memberName); sink(" = "); static if(is(typeof(__traits(getMember, this, memberName)) : const(char)[])) sink(__traits(getMember, this, memberName)); else static if(is(typeof(__traits(getMember, this, memberName)) : long)) { char[32] tmpBuff = void; sink(sizeToTempString(__traits(getMember, this, memberName), tmpBuff)); } // else pragma(msg, typeof(__traits(getMember, this, memberName))); sink("\n"); } } super.printMembers(sink); }}mixin template StaticHumanReadableMessage(string s) { override void getHumanReadableMessage(scope void delegate(in char[]) sink) const { sink(s); }}interface DynamicException { /* TypeInfo getArgumentType(size_t idx); void* getArgumentData(size_t idx); string getArgumentAsString(size_t idx); */}//动态异常template enforceBase(ExceptionBaseClass, string failureCondition = "ret is null") { auto enforceBase(alias func, string file = __FILE__, size_t line = __LINE__, T...)(T args) { auto ret = func(args); if(mixin(failureCondition)) { class C : ExceptionBaseClass, DynamicException { T args; this(T args) { this.args = args; } override void printMembers(scope void delegate(in char[]) sink) const { import std.traits; import std.conv; foreach(idx, arg; args) { sink("\t"); sink(ParameterIdentifierTuple!func[idx]); sink(" = "); sink(to!string(arg)); sink("\n"); } sink("\treturn value = "); sink(to!string(ret)); sink("\n"); } override void printName(scope void delegate(in char[]) sink) const { sink(__traits(identifier, ExceptionBaseClass)); } override void getHumanReadableMessage(scope void delegate(in char[]) sink) const { sink(__traits(identifier, func)); sink(" call failed"); } } auto exception = new C(args); exception.file = file; exception.line = line; throw exception; } return ret; }}/// 抛给定一组要打印的局部变量,异常void raise(ExceptionBaseClass, T...)(string file = __FILE__, size_t line = __LINE__) { class C : ExceptionBaseClass, DynamicException { override void printMembers(scope void delegate(in char[]) sink) const { import std.conv; foreach(idx, arg; T) { sink("\t"); sink(__traits(identifier, T[idx])); sink(" = "); sink(to!string(arg)); sink("\n"); } } override void printName(scope void delegate(in char[]) sink) const { sink(__traits(identifier, ExceptionBaseClass)); } } auto exception = new C(); exception.file = file; exception.line = line; throw exception;}const(char)[] sizeToTempString(long size, char[] buffer) { size_t pos = buffer.length - 1; bool negative = size < 0; if(size < 0) size = -size; while(size) { buffer[pos] = size % 10 + '0'; size /= 10; pos--; } if(negative) { buffer[pos] = '-'; pos--; } return buffer[pos + 1 .. $];}//示例:class MyRangeError : ErrorBase { // 不必要但有静态错误消息有点好 mixin StaticHumanReadableMessage!"越界";}// 创建新类class TypedRangeError(T) : MyRangeError { // 详细错误信息,在数据成员中 this(T index) { this.index = index; } mixin StaticHumanReadableMessage!(T.stringof ~ " index out of bounds"); // 提供了更多信息并且无需分配 T index; mixin PrintMembers;//插件.}version(exception_2_example) { // 可传递预先构造异常给函数,并得到良好的文件/行和堆栈跟踪信息 void stackExample(ThrowableBase exception) { // 抛 exception.fly(); // 抛语句 } void main() { int a = 230; string file = "lol"; static class BadValues : ExceptionBase {} //raise!(BadValues, a, file); alias enforce = enforceBase!ExceptionBase; import core.stdc.stdio; auto fp = enforce!fopen("nofile.txt".ptr, "rb".ptr); // 构造,按数据,而非串传递 auto exception = new TypedRangeError!int(4); // 异常构造与文件/行设置分离 stackExample(exception); // 可以在A分配/构造,然后在B地设置和抛出 }}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java中BigDecimal和0比较的示例代码
下一篇:极兔速递快递单号查询物流信息API(极兔速递快递单号查询物流信息网)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~