blob: 7c66f65af27cfcff214a63c4680a203d9881a80a [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* Error handling -- see also run.c */
2
3/* New error handling interface.
4
5 The following problem exists (existed): methods of built-in modules
6 are called with 'self' and 'args' arguments, but without a context
7 argument, so they have no way to raise a specific exception.
8 The same is true for the object implementations: no context argument.
9 The old convention was to set 'errno' and to return NULL.
10 The caller (usually call_function() in eval.c) detects the NULL
11 return value and then calls puterrno(ctx) to turn the errno value
12 into a true exception. Problems with this approach are:
13 - it used standard errno values to indicate Python-specific errors,
Guido van Rossum3f5da241990-12-20 15:06:42 +000014 but this means that when such an error code is reported by a system
15 call (e.g., in module posix), the user gets a confusing message
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000016 - errno is a global variable, which makes extensions to a multi-
17 threading environment difficult; e.g., in IRIX, multi-threaded
Guido van Rossum3f5da241990-12-20 15:06:42 +000018 programs must use the function oserror() instead of looking in errno
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000019 - there is no portable way to add new error numbers for specic
20 situations -- the value space for errno is reserved to the OS, yet
21 the way to turn module-specific errors into a module-specific
22 exception requires module-specific values for errno
23 - there is no way to add a more situation-specific message to an
24 error.
25
26 The new interface solves all these problems. To return an error, a
Guido van Rossum3f5da241990-12-20 15:06:42 +000027 built-in function calls err_set(exception), err_setval(exception,
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028 value) or err_setstr(exception, string), and returns NULL. These
29 functions save the value for later use by puterrno(). To adapt this
30 scheme to a multi-threaded environment, only the implementation of
31 err_setval() has to be changed.
32*/
33
Guido van Rossum3f5da241990-12-20 15:06:42 +000034#include "allobjects.h"
35
Guido van Rossumf22120a1990-12-20 23:05:40 +000036#include <errno.h>
37#ifndef errno
38extern int errno;
39#endif
40
Guido van Rossum3f5da241990-12-20 15:06:42 +000041#include "errcode.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000042
Guido van Rossumf5401bd1990-11-02 17:50:28 +000043extern char *strerror PROTO((int));
44
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000045/* Last exception stored by err_setval() */
46
47static object *last_exception;
48static object *last_exc_val;
49
50void
51err_setval(exception, value)
52 object *exception;
53 object *value;
54{
Guido van Rossum3f5da241990-12-20 15:06:42 +000055 XDECREF(last_exception);
56 XINCREF(exception);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057 last_exception = exception;
58
Guido van Rossum3f5da241990-12-20 15:06:42 +000059 XDECREF(last_exc_val);
60 XINCREF(value);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061 last_exc_val = value;
62}
63
64void
65err_set(exception)
66 object *exception;
67{
68 err_setval(exception, (object *)NULL);
69}
70
71void
72err_setstr(exception, string)
73 object *exception;
74 char *string;
75{
76 object *value = newstringobject(string);
77 err_setval(exception, value);
Guido van Rossum3f5da241990-12-20 15:06:42 +000078 XDECREF(value);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079}
80
81int
82err_occurred()
83{
84 return last_exception != NULL;
85}
86
87void
88err_get(p_exc, p_val)
89 object **p_exc;
90 object **p_val;
91{
92 *p_exc = last_exception;
93 last_exception = NULL;
94 *p_val = last_exc_val;
95 last_exc_val = NULL;
96}
97
98void
99err_clear()
100{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000101 XDECREF(last_exception);
102 last_exception = NULL;
103 XDECREF(last_exc_val);
104 last_exc_val = NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000105}
Guido van Rossum7d310eb1990-10-14 20:00:05 +0000106
107/* Convenience functions to set a type error exception and return 0 */
108
109int
110err_badarg()
111{
Guido van Rossumf1ac4031990-11-09 15:05:53 +0000112 err_setstr(TypeError, "illegal argument type for built-in operation");
Guido van Rossum7d310eb1990-10-14 20:00:05 +0000113 return 0;
114}
115
116object *
117err_nomem()
118{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000119 err_set(MemoryError);
Guido van Rossum7d310eb1990-10-14 20:00:05 +0000120 return NULL;
121}
122
123object *
124err_errno(exc)
125 object *exc;
126{
127 object *v = newtupleobject(2);
128 if (v != NULL) {
129 settupleitem(v, 0, newintobject((long)errno));
130 settupleitem(v, 1, newstringobject(strerror(errno)));
131 }
132 err_setval(exc, v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000133 XDECREF(v);
Guido van Rossum7d310eb1990-10-14 20:00:05 +0000134 return NULL;
135}
Guido van Rossum683a0721990-10-21 22:09:12 +0000136
137void
138err_badcall()
139{
140 err_setstr(SystemError, "bad argument to internal function");
141}
Guido van Rossum3f5da241990-12-20 15:06:42 +0000142
143/* Set the error appropriate to the given input error code (see errcode.h) */
144
145void
146err_input(err)
147 int err;
148{
149 switch (err) {
150 case E_DONE:
151 case E_OK:
152 break;
153 case E_SYNTAX:
154 err_setstr(RuntimeError, "syntax error");
155 break;
156 case E_TOKEN:
157 err_setstr(RuntimeError, "illegal token");
158 break;
159 case E_INTR:
160 err_set(KeyboardInterrupt);
161 break;
162 case E_NOMEM:
163 err_nomem();
164 break;
165 case E_EOF:
166 err_set(EOFError);
167 break;
168 default:
169 err_setstr(RuntimeError, "unknown input error");
170 break;
171 }
172}