blob: 7424b0cae1e6d64e60fa02c7ce1b5d8914961c77 [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 "errno.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000035
Guido van Rossum3f5da241990-12-20 15:06:42 +000036#include "allobjects.h"
37
38#include "errcode.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000039
Guido van Rossumf5401bd1990-11-02 17:50:28 +000040extern char *strerror PROTO((int));
41
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000042/* Last exception stored by err_setval() */
43
44static object *last_exception;
45static object *last_exc_val;
46
47void
48err_setval(exception, value)
49 object *exception;
50 object *value;
51{
Guido van Rossum3f5da241990-12-20 15:06:42 +000052 XDECREF(last_exception);
53 XINCREF(exception);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000054 last_exception = exception;
55
Guido van Rossum3f5da241990-12-20 15:06:42 +000056 XDECREF(last_exc_val);
57 XINCREF(value);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000058 last_exc_val = value;
59}
60
61void
62err_set(exception)
63 object *exception;
64{
65 err_setval(exception, (object *)NULL);
66}
67
68void
69err_setstr(exception, string)
70 object *exception;
71 char *string;
72{
73 object *value = newstringobject(string);
74 err_setval(exception, value);
Guido van Rossum3f5da241990-12-20 15:06:42 +000075 XDECREF(value);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076}
77
78int
79err_occurred()
80{
81 return last_exception != NULL;
82}
83
84void
85err_get(p_exc, p_val)
86 object **p_exc;
87 object **p_val;
88{
89 *p_exc = last_exception;
90 last_exception = NULL;
91 *p_val = last_exc_val;
92 last_exc_val = NULL;
93}
94
95void
96err_clear()
97{
Guido van Rossum3f5da241990-12-20 15:06:42 +000098 XDECREF(last_exception);
99 last_exception = NULL;
100 XDECREF(last_exc_val);
101 last_exc_val = NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000102}
Guido van Rossum7d310eb1990-10-14 20:00:05 +0000103
104/* Convenience functions to set a type error exception and return 0 */
105
106int
107err_badarg()
108{
Guido van Rossumf1ac4031990-11-09 15:05:53 +0000109 err_setstr(TypeError, "illegal argument type for built-in operation");
Guido van Rossum7d310eb1990-10-14 20:00:05 +0000110 return 0;
111}
112
113object *
114err_nomem()
115{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000116 err_set(MemoryError);
Guido van Rossum7d310eb1990-10-14 20:00:05 +0000117 return NULL;
118}
119
120object *
121err_errno(exc)
122 object *exc;
123{
124 object *v = newtupleobject(2);
125 if (v != NULL) {
126 settupleitem(v, 0, newintobject((long)errno));
127 settupleitem(v, 1, newstringobject(strerror(errno)));
128 }
129 err_setval(exc, v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000130 XDECREF(v);
Guido van Rossum7d310eb1990-10-14 20:00:05 +0000131 return NULL;
132}
Guido van Rossum683a0721990-10-21 22:09:12 +0000133
134void
135err_badcall()
136{
137 err_setstr(SystemError, "bad argument to internal function");
138}
Guido van Rossum3f5da241990-12-20 15:06:42 +0000139
140/* Set the error appropriate to the given input error code (see errcode.h) */
141
142void
143err_input(err)
144 int err;
145{
146 switch (err) {
147 case E_DONE:
148 case E_OK:
149 break;
150 case E_SYNTAX:
151 err_setstr(RuntimeError, "syntax error");
152 break;
153 case E_TOKEN:
154 err_setstr(RuntimeError, "illegal token");
155 break;
156 case E_INTR:
157 err_set(KeyboardInterrupt);
158 break;
159 case E_NOMEM:
160 err_nomem();
161 break;
162 case E_EOF:
163 err_set(EOFError);
164 break;
165 default:
166 err_setstr(RuntimeError, "unknown input error");
167 break;
168 }
169}