1 | #!/usr/bin/env python2
|
2 | """
|
3 | exceptions.py
|
4 | """
|
5 | from __future__ import print_function
|
6 |
|
7 | #from errno import EISDIR
|
8 | import os
|
9 | from mycpp.mylib import log, print_stderr
|
10 |
|
11 | from typing import List, Any
|
12 | #import posix_ as posix
|
13 |
|
14 |
|
15 | def Close(fd):
|
16 | # type: (int) -> None
|
17 |
|
18 | #raise OSError(EISDIR)
|
19 | raise OSError(0)
|
20 |
|
21 |
|
22 | def Pop(fd):
|
23 | # type: (int) -> None
|
24 |
|
25 | try:
|
26 | #posix.close(fd)
|
27 | Close(fd)
|
28 | except (IOError, OSError) as e:
|
29 | #log('Error closing descriptor %d: %s', rf.orig_fd, pyutil.strerror(e))
|
30 | log('Error closing descriptor %d', fd)
|
31 | raise
|
32 |
|
33 |
|
34 | def AppBundleMain(argv):
|
35 | # type: (List[str]) -> int
|
36 |
|
37 | Pop(3)
|
38 |
|
39 | return 0
|
40 |
|
41 |
|
42 | def TestRethrow():
|
43 | # type: () -> int
|
44 | """
|
45 | This is fine, the problem was throwing an exceptinon in a DESTRUCTOR
|
46 | """
|
47 | argv = [] # type: List[str]
|
48 |
|
49 | try:
|
50 | return AppBundleMain(argv)
|
51 |
|
52 | except ValueError as e:
|
53 | return 2
|
54 | #except error.Usage as e:
|
55 | # #builtin.Help(['oil-usage'], util.GetResourceLoader())
|
56 | # log('oil: %s', e.msg)
|
57 | # return 2
|
58 |
|
59 | except KeyboardInterrupt:
|
60 | print('')
|
61 | return 130 # 128 + 2
|
62 |
|
63 | except (IOError, OSError) as e:
|
64 | if 0:
|
65 | import traceback
|
66 | traceback.print_exc()
|
67 |
|
68 | # test this with prlimit --nproc=1 --pid=$$
|
69 | #print_stderr('osh I/O error (main): %s' % posix.strerror(e.errno))
|
70 | print_stderr('osh I/O error (main)')
|
71 | return 2 # dash gives status 2
|
72 |
|
73 |
|
74 | class ctx_TerminalControl(object):
|
75 |
|
76 | def __init__(self):
|
77 | # type: () -> None
|
78 |
|
79 | log('TerminalControl init')
|
80 |
|
81 | def __enter__(self):
|
82 | # type: () -> None
|
83 | pass
|
84 |
|
85 | def __exit__(self, type, value, traceback):
|
86 | # type: (Any, Any, Any) -> None
|
87 | log('TerminalControl exit')
|
88 |
|
89 | TestRethrow()
|
90 |
|
91 | # https://akrzemi1.wordpress.com/2011/09/21/destructors-that-throw/
|
92 |
|
93 | # Quote: Until any exception gets out from the destructor we can throw at
|
94 | # will inside, even from other destructors, and this does not account for
|
95 | # double-exception situation or "throwing from destructor during stack
|
96 | # unwinding." Let's illustrate it with an example.
|
97 | log('Throw and Catch within destructor seems OK')
|
98 |
|
99 |
|
100 | def TestDestructor():
|
101 | # type: () -> None
|
102 |
|
103 | with ctx_TerminalControl():
|
104 | log('hi')
|
105 |
|
106 |
|
107 | def run_tests():
|
108 | # type: () -> int
|
109 |
|
110 | TestRethrow()
|
111 |
|
112 | log('')
|
113 | log('TestDestructor')
|
114 | log('')
|
115 |
|
116 | TestDestructor()
|
117 |
|
118 | return 0
|
119 |
|
120 |
|
121 | def run_benchmarks():
|
122 | # type: () -> None
|
123 | raise NotImplementedError()
|
124 |
|
125 |
|
126 | if __name__ == '__main__':
|
127 | if os.getenv('BENCHMARK'):
|
128 | log('Benchmarking...')
|
129 | run_benchmarks()
|
130 | else:
|
131 | run_tests()
|