| // Author: Ali Çehreli |
| // See https://forum.dlang.org/post/o2n7f8$2p1t$1@digitalmars.com |
| |
| import core.stdc.stdio; |
| |
| class TestException : Exception |
| { |
| this(string msg) |
| { |
| super(typeof(this).stringof~": "~msg); |
| } |
| } |
| |
| class TestError : Error |
| { |
| this(string msg) |
| { |
| super(typeof(this).stringof~": "~msg); |
| } |
| } |
| |
| // Causes an exception chain where the node at index errorIndex is an |
| // Error (others are all Exceptions). |
| void causeExceptionChain(size_t chainLength, size_t errorIndex) |
| { |
| void throws(size_t n) |
| { |
| scope (exit) |
| { |
| string msg = [ cast(char)('a'+n) ].idup; |
| if (n == errorIndex) |
| { |
| throw new TestError(msg); |
| } |
| else |
| { |
| throw new TestException(msg); |
| } |
| } |
| |
| if (n != 0) |
| { |
| // Redundant 'return' keyword due to |
| // https://issues.dlang.org/show_bug.cgi?id=16960 |
| return throws(n - 1); |
| } |
| } |
| |
| throws(chainLength - 1); |
| } |
| |
| void main() |
| { |
| try |
| { |
| // -1 would mean "no Error in the chain". Change this to a |
| // number between 0 and 4 (inclusive) then you will realize |
| // that the Exception below will not be caught. |
| size_t errorIndex = 3; |
| causeExceptionChain(5, errorIndex); |
| } |
| catch (Error original) |
| { |
| printf("Caught\n"); |
| string prefix = ""; |
| for ({ size_t i; Throwable ex = original; } ex; ex = ex.next, ++i) |
| { |
| printf("%.*s%.*s\n", prefix.length, prefix.ptr, ex.msg.length, ex.msg.ptr); |
| prefix = prefix~" "; |
| } |
| printf("Bypassed chain was:\n"); |
| prefix = ""; |
| for ({ size_t i; Throwable ex = original.bypassedException; } ex; ex = ex.next, ++i) |
| { |
| printf("%.*s%.*s\n", prefix.length, prefix.ptr, ex.msg.length, ex.msg.ptr); |
| prefix = prefix~" "; |
| } |
| } |
| } |