chain.d revision 1.1.1.1
1// Author: Ali ��ehreli 2// See https://forum.dlang.org/post/o2n7f8$2p1t$1@digitalmars.com 3 4import core.stdc.stdio; 5 6class TestException : Exception 7{ 8 this(string msg) 9 { 10 super(typeof(this).stringof~": "~msg); 11 } 12} 13 14class TestError : Error 15{ 16 this(string msg) 17 { 18 super(typeof(this).stringof~": "~msg); 19 } 20} 21 22// Causes an exception chain where the node at index errorIndex is an 23// Error (others are all Exceptions). 24void causeExceptionChain(size_t chainLength, size_t errorIndex) 25{ 26 void throws(size_t n) 27 { 28 scope (exit) 29 { 30 string msg = [ cast(char)('a'+n) ].idup; 31 if (n == errorIndex) 32 { 33 throw new TestError(msg); 34 } 35 else 36 { 37 throw new TestException(msg); 38 } 39 } 40 41 if (n != 0) 42 { 43 // Redundant 'return' keyword due to 44 // https://issues.dlang.org/show_bug.cgi?id=16960 45 return throws(n - 1); 46 } 47 } 48 49 throws(chainLength - 1); 50} 51 52void main() 53{ 54 try 55 { 56 // -1 would mean "no Error in the chain". Change this to a 57 // number between 0 and 4 (inclusive) then you will realize 58 // that the Exception below will not be caught. 59 size_t errorIndex = 3; 60 causeExceptionChain(5, errorIndex); 61 } 62 catch (Error original) 63 { 64 printf("Caught\n"); 65 string prefix = ""; 66 for ({ size_t i; Throwable ex = original; } ex; ex = ex.next, ++i) 67 { 68 printf("%.*s%.*s\n", prefix.length, prefix.ptr, ex.msg.length, ex.msg.ptr); 69 prefix = prefix~" "; 70 } 71 printf("Bypassed chain was:\n"); 72 prefix = ""; 73 for ({ size_t i; Throwable ex = original.bypassedException; } ex; ex = ex.next, ++i) 74 { 75 printf("%.*s%.*s\n", prefix.length, prefix.ptr, ex.msg.length, ex.msg.ptr); 76 prefix = prefix~" "; 77 } 78 } 79} 80