# exceptions instead of errors

- Thread: https://externals.io/message/1192
- Original archive: https://news-web.php.net/php.internals/1192
- Started by marcus.boerger@t-online.de on 2003-05-04T00:53:30+00:00
- Messages: 9
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #1192 — marcus.boerger@t-online.de — 2003-05-04T00:53:30+00:00

URL: https://externals.io/message/1192#1192

The following patch:
http://marcus-boerger.de/php/ext/exception.diff

allows in a short, straight forward and easy way to suppress errors and
optionally throw exceptions instead. This is supposed to be automated
by the try opcode (but that is another discussion).

The problem:
During development of SQLite i found the problem that i had to inform
the user about an error inside a constructor. This can only be done by
throwing an exception. (Repeat: this cannot be done otherwise). The
main problem herin is that we have many little utility functions that may
raise errors (like safe mode and such).

This means we had to rewrite the whole api, pass information around
or find a generic solution.

Ok here goes:

First i fixed the "ignore repeated errors" feature. Then i added some control
information to struct _php_core_globals:
         error_handling_t  error_handling;
         zend_class_entry *exception_class;

error_handling can be one of EH_NORMAL, EH_SUPPRESS and EH_THROW
- EH_NORMAL is the normal way errors are handled
- EH_SUPPRESS means the error is stored but not shown (suppressed even)
- EH_THROW throws an exception of type PG(exception_class) or the default
   exception class if PG(exception_class) is NULL.

To manually change the mode or class there is the following function:
         PHPAPI void php_set_error_handling(error_handling_t 
error_handling, zend_class_entry *exception_class TSRMLS_DC)

The mechanism itself is located in the function php_error_cb which is called
during all error calls. So every error, warning or notice is catched. BUT of
corse the mechanism doesn't work with E_ERROR, `E_PARSE` or such. These
are real errors and are errors even after the patch.

The reason the exception class can be set is to easily support exception 
inheritance
for the lazy programmers.

The reason to support EH_SUPPRESS is for more sophisticated problems...

When the mechanismn throws an error it automatically sets these exception
properties:
- message        the error message
- file           the filename
- line           the line number in the file

Further more i suggest we add the severity to the default exception.

Some help of the engine would be good:
- automatically set EH_THROW mode at "try"
- automatically set EH_NORMAL mode at "catch" (first outmost catch)

If noone objects i will commit this on monday evening.

Unfortunately there is a memory leak in the exception handling itself but
that is another story...and will hopefully soon be fixed by somebody else.

Anybody interested can try the patch with my patched SQLite:
http://marcus-boerger.de/html/php/ext/sqlite/
and especially look into test sqlite_oo_020.phpt

regards
marcus


-- 
------------------->>> mailto:mail@marcus-boerger.de <<<------------------
"We are animals among animals, all children of matter,
save that we are the more disarmed. But since, unlike animals,
we know that we must die, let us prepare for that moment
by enjoying the life that has been given us by chance and for chance."
                                Umberto Eco, The island of the day before
--------------------->>> http://marcus-boerger.de <<<

---

## #1193 — marcus.boerger@t-online.de — 2003-05-04T00:56:19+00:00

URL: https://externals.io/message/1192#1193 · In reply to: #1192

At 02:53 04.05.2003, Marcus Börger wrote:
>[...]
>Anybody interested can try the patch with my patched SQLite:

Ha, to late here already
http://marcus-boerger.de/php/ext/sqlite/

---

## #1202 — Andi Gutmans — 2003-05-04T02:32:18+00:00

URL: https://externals.io/message/1192#1202 · In reply to: #1192

At 02:53 AM 5/4/2003 +0200, Marcus Börger wrote:
>Some help of the engine would be good:
>- automatically set EH_THROW mode at "try"
>- automatically set EH_NORMAL mode at "catch" (first outmost catch)

Huh? I think it's definitely not obvious that I'd want these to happen 
automatically. Actually I personally wouldn't, because I'd prefer PHP to 
continue the way it works and only use exceptions in user-land.

>If noone objects i will commit this on monday evening.

Please don't before this is discussed. We have discussed this kind of thing 
quite a few times and our opinion was that error handling in PHP shouldn't 
be changed. We wouldn't want some configuration switch to change how the 
scripts work nor is it a good idea if the same script behaves differently 
according to one switch.
Anyway, we can discuss this again but definitely I don't think we should 
jump the gun with commits in this area until people really think of the 
whole picture. We have a large user base out there and we still want all of 
the user-base to "talk" in the same language.
I won't really be around for the next two weeks so maybe it's best to wait 
or in the least make sure Zeev takes part in this discussion.
Thanks,
Andi

P.S. -BTW, what does SQLite do?

---

## #1218 — marcus.boerger@t-online.de — 2003-05-04T17:21:35+00:00

URL: https://externals.io/message/1192#1218 · In reply to: #1192

At 04:32 04.05.2003, Andi Gutmans wrote:
>At 02:53 AM 5/4/2003 +0200, Marcus Börger wrote:
> > […]
>
>Huh? I think it's definitely not obvious that I'd want these to happen 
>automatically. Actually I personally wouldn't, because I'd prefer PHP to 
>continue the way it works and only use exceptions in user-land.
>
> > […]
>
>Please don't before this is discussed. We have discussed this kind of 
>thing quite a few times and our opinion was that error handling in PHP 
>shouldn't be changed. We wouldn't want some configuration switch to change 
>how the scripts work nor is it a good idea if the same script behaves 
>differently according to one switch.

There will surely no switch, that would be the stuiest thing we cold do.

>Anyway, we can discuss this again but definitely I don't think we should 
>jump the gun with commits in this area until people really think of the 
>whole picture. We have a large user base out there and we still want all 
>of the user-base to "talk" in the same language.

Large user base? Who the hell uses ze2 or php5 widely out there?
The patch is intended for the new php5/ze2 oo features and will not change 
any php4 features or its behavior.
It simply makes it possible to throw exceptions in ctors (and for that 
there is now other solution).

Everything else the patch offers can surely be discussed: automation with 
try/catch and so on.

What i like would be:

1) procedural (aka php4) no change (aka simply errors as of now)
2) oo (aka new php5/ze2 features) always throw exceptions instead of errors.

for example:

let's assume we have an extension "example" consisting of a function 
"example_test", a namespace "example"
containing a function "factory" and a class "whatever" with a "whatelse":

example_test(); //-> normal operation or error mechanism

$obj = example::factory(); // -> object creation or exception
$obj = new example::whatever(); // -> object creation or exception

$obj->whatelse(); // -> normal operation or exception

WHY: becasue this only changes new things we don't have yet and it is easy 
to learn
and deal with: "procedural = errors, oo = exceptions".


>I won't really be around for the next two weeks so maybe it's best to wait 
>or in the least make sure Zeev takes part in this discussion.

Then i hope you can answer now :-)

>Thanks,
>Andi
>
>P.S. -BTW, what does SQLite do?


Just as Wez said. And you may take a look at my patches and tests for it on 
the url i gave. Because this
extension lets you test exceptions with ctors and the factory() function.

regards
marcus

---

## #1236 — marcus.boerger@t-online.de — 2003-05-04T19:48:45+00:00

URL: https://externals.io/message/1192#1236 · In reply to: #1192

At 20:17 04.05.2003, l0t3k wrote:
>along the lines of this discussion, i had posted a (ignored) message
>concerning the behaviour of zend_parse_parameters. my point was/is that
>there should be an extra parameter which determines whether a regular PHP
>error or exception is raised. otherwise its useless to use in an OO
>extension (particularly in the case of constructors). if we adopt this
>approach, i think we'd also need an IllegalArgumentException or somesuch.

My patch opens the doors to such behavior :-)

regards
marcus

---

## #1253 — Daniel Lorch — 2003-05-05T10:59:55+00:00

URL: https://externals.io/message/1192#1253

hi,

> Just a note that I'd really like to see this.  One of the great things
> about exceptions will be:
> 
> try {
>   $m = mysql_connect("localhost", "user", "pass");
>   $sth = mysql_query("select bar from foo", $m);
>   while ($row = mysql_fetch_array($sth)) {
>     echo $row[0];
>   }
>   mysql_close($m);
> } catch (exception $e) {
>   echo $e->getMessage();
> }
> 
> This allows you to remove all the nasty if ($conn) could, and move your
> error handling into a singular place. [..]

Read more here:

  http://java.sun.com/docs/books/tutorial/essential/exceptions/definition.html

Basically try/catch-statements allow you to keep the main code block short
and readable because the error handling code is moved somewhere else. Would
be nice seeing this in PHP.

-daniel

---

## #1274 — Terence — 2003-05-05T15:48:59+00:00

URL: https://externals.io/message/1192#1274 · In reply to: #1253

some questions

Daniel Lorch wrote:
> hi,
> 
> 
> > […]

Is "exception" class built in? if so, extendable by users?
if not, how does getMessage() know where to find the error - especially 
if this error is produced by an extension.

> > […]
> 
> 
> Read more here:
> 
>   http://java.sun.com/docs/books/tutorial/essential/exceptions/definition.html
> 

And reading the article, one can see that it relys on types to bubble up 
and be cought correctly.

> Basically try/catch-statements allow you to keep the main code block short
> and readable because the error handling code is moved somewhere else. Would
> be nice seeing this in PHP.
> 
> -daniel

---

## #1437 — Derick Rethans — 2003-05-11T14:23:39+00:00

URL: https://externals.io/message/1192#1437

> Just a note that I'd really like to see this.  One of the great things
> about exceptions will be:
> 
> try {
>   $m = mysql_connect("localhost", "user", "pass");
>   $sth = mysql_query("select bar from foo", $m);
>   while ($row = mysql_fetch_array($sth)) {
>     echo $row[0];
>   }
>   mysql_close($m);
> } catch (exception $e) {
>   echo $e->getMessage();
> }
> 
> This allows you to remove all the nasty if ($conn) could, and move your
> error handling into a singular place. I *really* would like this for
> internal functions.  We could also make a new type of exception
> "internalexception," which a user has to specifically catch.  This way
> unless you explictly specify that you want to catch an
> internalexception, it will default to just outputting an error message.

Sounds like a great idea to me!

Derick

-- 
                                        "my other box is your windows PC"
-------------------------------------------------------------------------
 Derick Rethans                                 http://derickrethans.nl/ 
 PHP Magazine - PHP Magazine for Professionals       http://php-mag.net/

---

## #1442 — Theo Spears — 2003-05-11T15:40:51+00:00

URL: https://externals.io/message/1192#1442

> Just a note that I'd really like to see this.  One of the great things
> about exceptions will be:
>
> try {
>   $m = mysql_connect("localhost", "user", "pass");
>   $sth = mysql_query("select bar from foo", $m);
>   while ($row = mysql_fetch_array($sth)) {
>     echo $row[0];
>   }
>   mysql_close($m);
> } catch (exception $e) {
>   echo $e->getMessage();
> }
>
> This allows you to remove all the nasty if ($conn) could, and move your
> error handling into a singular place. I *really* would like this for
> internal functions.  We could also make a new type of exception
> "internalexception," which a user has to specifically catch.  This way
> unless you explictly specify that you want to catch an
> internalexception, it will default to just outputting an error message.
>
Although this approach would certainly simplify handling errors it seems to me 
it would give everyone big problems when it comes to predicting the control 
flow of their programs. For example

function db_connect ( $db_name ) {
  $link = mysql_connect();
  if ( ! mysql_select_db( $db_name, $link ) ) {
    mysql_select_db ( BACKUP_DB_NAME, $link );
  }
}

now, depending on whether you do

try {
  db_connect ( 'foo' );
} catch (exception e) {
}

or just 

db_connect ( 'foo' );

The function will behave differently. Even if all new PHP5 code uses 
exceptions there is a lot of code which doesn't, and so the principles of 
information hiding say you would have to make sure any code which calls a 
function in a separate module has to make sure that function isn't inside a 
try{}catch{} block, and the only functions in the same module which are 
inside try{}catch{} blocks that catch internal exceptions don't call any 
functions in external modules.

Personally I would prefer a system similar to the @ notation which suppresses 
error messages, possibly make %function() or similar cause the function to 
raise an exception. (The engine could handle this by silently dropping all 
exceptions from internal functions that weren't called with the relevant 
prefix).

Just my £0.02

Theo Spears
