# Continued try blocks

- Thread: https://externals.io/message/67167
- Original archive: https://news-web.php.net/php.internals/67167
- Started by Julien Pauli on 2013-04-26T14:41:17+00:00
- Messages: 32
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/67167.md?page=2
- 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

---

## #67167 — Julien Pauli — 2013-04-26T14:41:17+00:00

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

Hello internals,

I had an idea recently with a friend, about a feature try-catch blocks
could use.
Let me just write an example, you will quickly understand the idea :

*<?php*
*
*
*try {*
*   foo();*
*   bar();*
*   baz();*
*} catch (SomeException $e) {*
*    dosomestuff();*
*    continue; /* Here is the feature, go back to try block */*
*} catch (Exception $e) {*
*    dosomething();*
*}*



The continue keyword would resume the execution from where it had
diverged, according to the function which led to the SomeException
catch block.

So, in this example, if, say, bar() throws a SomeException , the code
would then resume and execute baz() after the catch block.

Just presenting the idea here, no RFC actually , I'm collecting
thoughts and notices.

Julien.Pauli

---

## #67168 — syragg@gmail.com — 2013-04-26T14:46:05+00:00

URL: https://externals.io/message/67167#67168 · In reply to: #67167

Sounds interesting. And what about the second attempt passing the try block
without goto?


2013/4/26 Julien Pauli <jpauli@php.net>

> Hello internals,
>
> I had an idea recently with a friend, about a feature try-catch blocks
> could use.
> Let me just write an example, you will quickly understand the idea :
>
> *<?php*
> *
> *
> *try {*
> *   foo();*
> *   bar();*
> *   baz();*
> *} catch (SomeException $e) {*
> *    dosomestuff();*
> *    continue; /* Here is the feature, go back to try block */*
> *} catch (Exception $e) {*
> *    dosomething();*
> *}*
>
>
>
> The continue keyword would resume the execution from where it had
> diverged, according to the function which led to the SomeException
> catch block.
>
> So, in this example, if, say, bar() throws a SomeException , the code
> would then resume and execute baz() after the catch block.
>
> Just presenting the idea here, no RFC actually , I'm collecting
> thoughts and notices.
>
> Julien.Pauli

---

## #67169 — Lazare Inepologlou — 2013-04-26T15:22:42+00:00

URL: https://externals.io/message/67167#67169 · In reply to: #67167

2013/4/26 Julien Pauli <jpauli@php.net>

> Hello internals,
>
> I had an idea recently with a friend, about a feature try-catch blocks
> could use.
> Let me just write an example, you will quickly understand the idea :
>
> *<?php*
> *
> *
> *try {*
> *   foo();*
> *   bar();*
> *   baz();*
> *} catch (SomeException $e) {*
> *    dosomestuff();*
> *    continue; /* Here is the feature, go back to try block */*
> *} catch (Exception $e) {*
> *    dosomething();*
> *}*
>
>

This seems like a BC break:

for ( ; ; )  {
  try {
    ...
  } catch (Exception $e) {
    continue;
  }
}

With the proposed syntax, "continue" will no longer refer to the "for" loop.



>
>
> The continue keyword would resume the execution from where it had
> diverged, according to the function which led to the SomeException
> catch block.
>
> So, in this example, if, say, bar() throws a SomeException , the code
> would then resume and execute baz() after the catch block.
>
> Just presenting the idea here, no RFC actually , I'm collecting
> thoughts and notices.
>
> Julien.Pauli
>


Lazare INEPOLOGLOU
Ingénieur Logiciel

---

## #67170 — Patrick Schaaf — 2013-04-26T15:47:41+00:00

URL: https://externals.io/message/67167#67170 · In reply to: #67167

On Friday 26 April 2013 16:41:17 Julien Pauli wrote:

> *try {*
> *   foo();*
> *   bar();*
> *   baz();*
> *} catch (SomeException $e) {*
> *    dosomestuff();*
> *    continue; /* Here is the feature, go back to try block */*
> *} catch (Exception $e) {*
> *    dosomething();*
> *}*
>... 
> So, in this example, if, say, bar() throws a SomeException , the code
> would then resume and execute baz() after the catch block.

What exactly would it "continue" with?

The next instruction after whereever the "throw" was?

The toplevel function call (or other code) next after the toplevel function in 
the try block that threw up?

The first answer won't work because any object live when bar() threw but only 
referenced in the call stack below the try block, will already have been 
destructed.

The second answer appears ... semantically dubious.

best regards
  Patrick

---

## #67171 — Amaury Bouchard — 2013-04-26T16:51:47+00:00

URL: https://externals.io/message/67167#67171 · In reply to: #67170

I will answer, as the idea came from Pierrick Charron and I  :-)

Sometimes, you call functions (or methods) and you know they can throw some
exceptions. But you don't want to stop all computations just because one of
them raised an exception. Maybe you just want to log it, and go to the next
call.

If you write that:

 try {
     $o->method1();
     $o->method2();
     $o->method3();
 } catch (Exception $e) {
     add_to_log($e->getMessage());
 }

If method1() raises an exception, it's not possible to execute method2().
And so it forces us to write ugly code like that:

 try {
     $o->method1();
 } catch (Exception $e) {
     add_to_log($e->getMessage());
 }
 try {
     $o->method2();
 } catch (Exception $e) {
     add_to_log($e->getMessage());
 }
 try {
     $o->method3();
 } catch (Exception $e) {
     add_to_log($e->getMessage());
 }

But honestly, nobody uses a try/catch block for every single line of code!
Unfortunately, it's sometimes the only solution...


What I'm suggesting is to be able to continue the code execution, from to
point where an exception was raised.

 try {
     $o->method1();
     $o->method2();
     $o->method3();
 } catch (Exception $e) {
     add_to_log($e->getMessage());
     continue;
 }

In this example, if method1() raises an exception, it will be logged, and
then method2() will be called.
If method2() raises an exception, it will be logged, and then method3()
will be called.
Is method3() raises an exception, it will be logged, and the execution will
continue after the try/catch block.

"continue" is the best keyword for that: The meaning is "please, continue
the execution of my code"  :-)


As Julien said, there is a BC break, when a try/catch block is written
inside a loop. But I think it's not a major usage, and it's a minor
inconvenient.


Amaury



2013/4/26 Patrick Schaaf <php@bof.de>

> On Friday 26 April 2013 16:41:17 Julien Pauli wrote:
>
> > […]
>
> What exactly would it "continue" with?
>
> The next instruction after whereever the "throw" was?
>
> The toplevel function call (or other code) next after the toplevel
> function in
> the try block that threw up?
>
> The first answer won't work because any object live when bar() threw but
> only
> referenced in the call stack below the try block, will already have been
> destructed.
>
> The second answer appears ... semantically dubious.
>
> best regards
>   Patrick

---

## #67172 — Kalle Sommer Nielsen — 2013-04-26T17:14:54+00:00

URL: https://externals.io/message/67167#67172 · In reply to: #67169

Hi

2013/4/26 Lazare Inepologlou <linepogl@gmail.com>:
> This seems like a BC break:
>
> for ( ; ; )  {
>   try {
>     ...
>   } catch (Exception $e) {
>     continue;
>   }
> }
>
> With the proposed syntax, "continue" will no longer refer to the "for" loop.

Well, at the moment "continue" is assigned to only usage in loops, we
also have "break" (switch) which works for both loops and construct,
if break is used inside a construct, thats inside a loop, it will be
seen as a part of the construct, we could change continue to work the
same as that.


-- 
regards,

Kalle Sommer Nielsen
kalle@php.net

---

## #67175 — Andreas Heigl — 2013-04-26T19:15:06+00:00

URL: https://externals.io/message/67167#67175 · In reply to: #67167

Am 26.04.13 16:41, schrieb Julien Pauli:
> Hello internals,
> 
> I had an idea recently with a friend, about a feature try-catch blocks
> could use.
> Let me just write an example, you will quickly understand the idea :
> 
> *<?php*
> *
> *
> *try {*
> *   foo();*
> *   bar();*
> *   baz();*
> *} catch (SomeException $e) {*
> *    dosomestuff();*
> *    continue; /* Here is the feature, go back to try block */*
> *} catch (Exception $e) {*
> *    dosomething();*
> *}*
> 
> 
> 
> The continue keyword would resume the execution from where it had
> diverged, according to the function which led to the SomeException
> catch block.
> 
> So, in this example, if, say, bar() throws a SomeException , the code
> would then resume and execute baz() after the catch block.
> 
> Just presenting the idea here, no RFC actually , I'm collecting
> thoughts and notices.
> 
> Julien.Pauli
> 
Hi Julien.

What about the following example?

try {
    $foo = $bar->getObject();
    $foo->doSomething()
} catch(Exception $e) {
    continue // Or whatever shall be used
}

When $bar->getObject throws an Exception no $foo is set. So the next
line will result in a "PHP Fatal error:  Call to a member function
doSomething() on a non-object".

So where shall the "continue" actually continue? In the line after the
exception was thrown? In the line following the last line $foo was
accessed in?

Or would something like

CreateTryCatchBlockForEverySingleLine {
    $bar->doOne();
    $bar->doNext();
    $bar->doSomethingElse();
} catch(Exception $e) {
    doSomethingWithTheException($e);
}

resulting in

try {
    $bar->doOne();
} catch(Exception $e) {
    doSomethingWithTheException($e);
}
try {
    $bar->doNext();
} catch(Exception $e) {
    doSomethingWithTheException($e);
}
try {
    $bar->doSomethingElse();
} catch(Exception $e) {
    doSomethingWithTheException($e);
}

be more what you are talking about?

Regards

Andreas

-- 
                                                              ,,,
                                                             (o o)
+---------------------------------------------------------ooO-(_)-Ooo-+
| Andreas Heigl                                                       |
| mailto:andreas@heigl.org                  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org                       http://hei.gl/wiFKy7 |
+---------------------------------------------------------------------+
| http://hei.gl/root-ca                                               |
+---------------------------------------------------------------------+

---

## #67176 — Robert Stoll — 2013-04-26T19:39:51+00:00

URL: https://externals.io/message/67167#67176 · In reply to: #67175

I like the idea but would prefer another control structure such as
CreateTryCatchBlockForEverySingleLine (should be shorter though) rather than
continue.
The continue keyword is confusing in my opinion.  And I would say it should
be for every single statement whereupon a statement is defined by either ;
or {} rather then for every single line.
Thus the following code:

tryStatements{
  $a = foo();
  if($a > 1){
    $i = bar();
  }else{
    $i = muu();
  }
  for(;$i<10;$i++){
    //..
  }
}catch(Exception $ex){
  log($ex);
}

Would result in:

try{
      $a = foo();
} catch(Exception $ex){
  log($ex);
}
try{
  if($a > 1){
    $i = bar();
  }else{
    $i = muu();
  }
} catch(Exception $ex){
  log($ex);
}
try{
  for(;$i<10;$i++){
    //..
  }
} catch(Exception $ex){
  log($ex);
}


-----Ursprüngliche Nachricht-----
Von: Andreas Heigl [mailto:andreas@heigl.org] 
Gesendet: Freitag, 26. April 2013 20:15
An: Julien Pauli
Cc: PHP Internals
Betreff: Re: [PHP-DEV] Continued try blocks

Am 26.04.13 16:41, schrieb Julien Pauli:
> Hello internals,
> 
> I had an idea recently with a friend, about a feature try-catch blocks
> could use.
> Let me just write an example, you will quickly understand the idea :
> 
> *<?php*
> *
> *
> *try {*
> *   foo();*
> *   bar();*
> *   baz();*
> *} catch (SomeException $e) {*
> *    dosomestuff();*
> *    continue; /* Here is the feature, go back to try block */*
> *} catch (Exception $e) {*
> *    dosomething();*
> *}*
> 
> 
> 
> The continue keyword would resume the execution from where it had
> diverged, according to the function which led to the SomeException
> catch block.
> 
> So, in this example, if, say, bar() throws a SomeException , the code
> would then resume and execute baz() after the catch block.
> 
> Just presenting the idea here, no RFC actually , I'm collecting
> thoughts and notices.
> 
> Julien.Pauli
> 
Hi Julien.

What about the following example?

try {
    $foo = $bar->getObject();
    $foo->doSomething()
} catch(Exception $e) {
    continue // Or whatever shall be used
}

When $bar->getObject throws an Exception no $foo is set. So the next
line will result in a "PHP Fatal error:  Call to a member function
doSomething() on a non-object".

So where shall the "continue" actually continue? In the line after the
exception was thrown? In the line following the last line $foo was
accessed in?

Or would something like

CreateTryCatchBlockForEverySingleLine {
    $bar->doOne();
    $bar->doNext();
    $bar->doSomethingElse();
} catch(Exception $e) {
    doSomethingWithTheException($e);
}

resulting in

try {
    $bar->doOne();
} catch(Exception $e) {
    doSomethingWithTheException($e);
}
try {
    $bar->doNext();
} catch(Exception $e) {
    doSomethingWithTheException($e);
}
try {
    $bar->doSomethingElse();
} catch(Exception $e) {
    doSomethingWithTheException($e);
}

be more what you are talking about?

Regards

Andreas

-- 
                                                              ,,,
                                                             (o o)
+---------------------------------------------------------ooO-(_)-Ooo-+
| Andreas Heigl                                                       |
| mailto:andreas@heigl.org                  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org                       http://hei.gl/wiFKy7 |
+---------------------------------------------------------------------+
| http://hei.gl/root-ca                                               |
+---------------------------------------------------------------------+

---

## #67177 — Amaury Bouchard — 2013-04-26T19:52:16+00:00

URL: https://externals.io/message/67167#67177 · In reply to: #67175

2013/4/26 Andreas Heigl <andreas@heigl.org>

> try {
>     $foo = $bar->getObject();
>     $foo->doSomething()
> } catch(Exception $e) {
>     continue // Or whatever shall be used
> }
>
> When $bar->getObject throws an Exception no $foo is set. So the next
> line will result in a "PHP Fatal error:  Call to a member function
> doSomething() on a non-object".
>

That's fine to me.

It's a software engineering problem you can solve easily:

 try {
     $foo = $bar->getObject();
     $foo->doSomething();
 } catch (ObjectCreationException $oce) {
     add_to_log('Unable to create object');
     throw $oce; // or do something else,
     // or just do nothing to exit from the try/catch block
 } catch (Exception $e) {
     add_to_log($e->getMessage());
     continue;
 }

The getObject() method should raise an ObjectCreationException, while the
doSomething() method could raise any other type of exception.
It's just a natural and smart way to use exceptions.


It could be solve differently:

 try {
     $foo = $bar->getObject();
     $foo->doSomething();
 } catch (NotImportantException $nie) {
     add_to_log($nie->getMessage());
     continue;
 } catch (Exception $e) {
     add_to_log($e->getMessage());
     throw $e; // or do something else,
     // or just do nothing to exit from the try/catch block
 }

If an expression raises a NotImportantException, it will not interrupt the
execution flow.

---

## #67178 — Ferenc Kovacs — 2013-04-27T12:16:07+00:00

URL: https://externals.io/message/67167#67178 · In reply to: #67171

> As Julien said, there is a BC break, when a try/catch block is written
> inside a loop. But I think it's not a major usage, and it's a minor
> inconvenient.

Yeah, and catching and discarding exceptions also possible, albeit a minor
inconvinience.
I don't have a strong opinion on this feature(albeit I think it isn't a
coincidence that most languages doesn't offer a dedicated solution to this
problem) but please don't reuse the continue keyword for it.
There are a bunch of code out there where which uses exceptions in a loop
context.
For example you have a retry counter decremented in a loop and you catch
the exceptions and retry until the retry limit is reached.

---

## #67181 — Amaury Bouchard — 2013-04-27T13:56:56+00:00

URL: https://externals.io/message/67167#67181 · In reply to: #67178

2013/4/27 Ferenc Kovacs <tyra3l@gmail.com>

> please don't reuse the continue keyword for it.
>
> There are a bunch of code out there where which uses exceptions in a loop
> context.
> For example you have a retry counter decremented in a loop and you catch
> the exceptions and retry until the retry limit is reached.
>
Fair enough. We can use "resume".

 try {
     doThis();
     doThat();
 } catch (NotImportantException $nie) {
     addToLog($nie->getMessage());
     resume;
 } catch (Exception $e) {
     cleanupEverything();
 }

---

## #67182 — Daniel Macedo — 2013-04-27T14:26:19+00:00

URL: https://externals.io/message/67167#67182 · In reply to: #67181

Sorry but I disagree, I think you're approaching try-catch wrong.

You shouldn't have a try-catch that *can* continue on the next line after
the throw.
What you should do is have decoupled code that handles _their own
exceptions_ nicely and either cleans up after itself else it rethrows the
exception/a new one.

Any top level try-catch is supposed to be a control structure with one of
two chances: either lines 1-N go smoothly and no exceptions are thrown, or
Exception_X is thrown and you clean up on it's catch block...

Also remember that you have the finally block.

---

## #67183 — Amaury Bouchard — 2013-04-27T18:22:38+00:00

URL: https://externals.io/message/67167#67183 · In reply to: #67182

2013/4/27 Daniel Macedo <admacedo@gmail.com>

> Sorry but I disagree, I think you're approaching try-catch wrong.
>
> You shouldn't have a try-catch that *can* continue on the next line after
> the throw.
> What you should do is have decoupled code that handles _their own
> exceptions_ nicely and either cleans up after itself else it rethrows the
> exception/a new one.
>
> Any top level try-catch is supposed to be a control structure with one of
> two chances: either lines 1-N go smoothly and no exceptions are thrown, or
> Exception_X is thrown and you clean up on it's catch block...
>

It's an opinion, a software engineering choice. Not something that must be
enforced by the language.

It could be very useful in some situations, not all the time (as traits,
for example).
Ideally, every errors (in fact, any abnormal situation) should raise an
exception, right? OK, but that doesn't mean that any abnormal situation
should be able to break execution flow, with no other solution than writing
more code.


Also remember that you have the finally block.
>

Can you explain how the finally block can help in my example?

---

## #67184 — Robert Stoll — 2013-04-27T18:46:19+00:00

URL: https://externals.io/message/67167#67184 · In reply to: #67183

I agree with Amaury. 
Although, it is rather smelly code to use try/catch as control flow
instrument, in some situations it is clearer to do it this way. 
I think the new construct would be especially useful if one just wants to
log errors (no further exception handling is necessary) as shown in previous
examples. 

-----Ursprüngliche Nachricht-----
Von: amaury.bouchard@gmail.com [mailto:amaury.bouchard@gmail.com] Im Auftrag
von Amaury Bouchard
Gesendet: Samstag, 27. April 2013 19:23
An: Daniel Macedo
Cc: Ferenc Kovacs; Julien Pauli; PHP Internals; Patrick Schaaf
Betreff: Re: [PHP-DEV] Continued try blocks

2013/4/27 Daniel Macedo <admacedo@gmail.com>

> Sorry but I disagree, I think you're approaching try-catch wrong.
>
> You shouldn't have a try-catch that *can* continue on the next line 
> after the throw.
> What you should do is have decoupled code that handles _their own 
> exceptions_ nicely and either cleans up after itself else it rethrows 
> the exception/a new one.
>
> Any top level try-catch is supposed to be a control structure with one 
> of two chances: either lines 1-N go smoothly and no exceptions are 
> thrown, or Exception_X is thrown and you clean up on it's catch block...
>

It's an opinion, a software engineering choice. Not something that must be
enforced by the language.

It could be very useful in some situations, not all the time (as traits, for
example).
Ideally, every errors (in fact, any abnormal situation) should raise an
exception, right? OK, but that doesn't mean that any abnormal situation
should be able to break execution flow, with no other solution than writing
more code.


Also remember that you have the finally block.
>

Can you explain how the finally block can help in my example?

---

## #67185 — Julien Pauli — 2013-04-28T15:27:47+00:00

URL: https://externals.io/message/67167#67185 · In reply to: #67181

> 2013/4/27 Ferenc Kovacs <tyra3l@gmail.com>
>
> > […]
> Fair enough. We can use "resume".
>

"continue" is just a keyword (syntactic sugar) we sure can change, I like
"resume" yes :-)

Julien.Pauli

---

## #67190 — Lars Strojny — 2013-04-29T06:25:29+00:00

URL: https://externals.io/message/67167#67190 · In reply to: #67167

Hi Julien,

I'm still on the fence, not sure if it isn’t too opaque.

Am 26.04.2013 um 16:41 schrieb Julien Pauli <jpauli@php.net>:
[...]

One question regarding scoping: does the next statement inherit the scope of the catch block like this?

try {
   $user = $repository->findById(123);
   $user->setName($name);
   $em->save($user);
   return true;
} catch (NotFoundException $e) {
   $user = new User();
   continue;
} catch (ValidationException $e) {
   $user->setName($this->stripInvalidChars($name));
   continue;
} catch (PersistenceException $e) {
   return false;
}

cu,
Lars

---

## #67195 — Camilo Sperberg — 2013-04-29T07:16:08+00:00

URL: https://externals.io/message/67167#67195 · In reply to: #67185

> 
> 
> > […]
> 
> "continue" is just a keyword (syntactic sugar) we sure can change, I like
> "resume" yes :-)
> 
> Julien.Pauli

And how about a restart instead of resume? I have used try catch blocks as a type of transactional block, so I think it would be nice if I could restart the entire block instead of resuming from the last point where it failed:

$blue = 'blue';
try {
    $data = a($blue);
    b($data); // This throws the dataIntegrityException
    c();
} catch (dataIntegrityException $e) {
    $blue = 'is the new red';
    restart; // executes a(), b() and c() again
} catch (Exception $e) {
    rollback();
}

Greetings.

---

## #67198 — Amaury Bouchard — 2013-04-29T07:25:59+00:00

URL: https://externals.io/message/67167#67198 · In reply to: #67195

Why not. But it will come in addition to "resume", not instead of it.
Then:
- "resume" => continue execution just after the point where the exception
was raised.
- "restart" => restart the whole try block.

I don't understand the meaning of your "rollback".


2013/4/29 Camilo Sperberg <unreal4u@gmail.com>

>
> 
>
> > […]
> wrote:
> > […]
> loop
> > […]
> catch
> > […]
>
> And how about a restart instead of resume? I have used try catch blocks as
> a type of transactional block, so I think it would be nice if I could
> restart the entire block instead of resuming from the last point where it
> failed:
>
> $blue = 'blue';
> try {
>     $data = a($blue);
>     b($data); // This throws the dataIntegrityException
>     c();
> } catch (dataIntegrityException $e) {
>     $blue = 'is the new red';
>     restart; // executes a(), b() and c() again
> } catch (Exception $e) {
>     rollback();
> }
>
> Greetings.

---

## #67196 — Camilo Sperberg — 2013-04-29T07:36:00+00:00

URL: https://externals.io/message/67167#67196 · In reply to: #67198

> Why not. But it will come in addition to "resume", not instead of it.
> Then:
> - "resume" => continue execution just after the point where the exception was raised.
> - "restart" => restart the whole try block.
> 
> I don't understand the meaning of your "rollback".
> 
> 
> 2013/4/29 Camilo Sperberg <unreal4u@gmail.com>
> 
> 
> 
> > […]
> 
> And how about a restart instead of resume? I have used try catch blocks as a type of transactional block, so I think it would be nice if I could restart the entire block instead of resuming from the last point where it failed:
> 
> $blue = 'blue';
> try {
>     $data = a($blue);
>     b($data); // This throws the dataIntegrityException
>     c();
> } catch (dataIntegrityException $e) {
>     $blue = 'is the new red';
>     restart; // executes a(), b() and c() again
> } catch (Exception $e) {
>     rollback();
> }
> 
> Greetings.
> 


It was just to denote the nature of a transaction block, nothing important ;)

---

## #67187 — johannes@schlueters.de — 2013-04-29T07:41:06+00:00

URL: https://externals.io/message/67167#67187 · In reply to: #67167

> Hello internals,
> 
> I had an idea recently with a friend, about a feature try-catch blocks
> could use.
> Let me just write an example, you will quickly understand the idea :
> 
> *<?php*
> *
> *
> *try {*
> *   foo();*
> *   bar();*
> *   baz();*
> *} catch (SomeException $e) {*
> *    dosomestuff();*
> *    continue; /* Here is the feature, go back to try block */*
> *} catch (Exception $e) {*
> *    dosomething();*
> *}*

this has quite a few issues and feels like abusing exceptions for
regular control flow.
The primary issue is that "throw" is a terminating operation. A
developer expects the following statements not tobe executed. To ensure
this in future a developer has to write

    if ($error) {
        throw new Exception();
        die("continue not allowed");
    }

This makes writing roust library code more complex. An alternative might
be to have "recoverable exceptions"

    if ($error) {
        throw new RecoverableException();
        // might continue here
    }

but this is weird, too: I know this situation can be fixed and prepare
my code to be fixed from the outside ... so why use exceptions for that?
An alternative might be to have a "error situation fixing component"
passed in (dependency injection like)

Throwing exceptions and jumping back and forth makes the code really
hard to follow.

Those things aside there are technical complications: We can't unwind
the stack anymore during the throw operation but have to put it aside,
execute all relevant catch blocks and then either recover it or throw it
away. So looking at this code:

function foo() {
   $o = new Class();
   if ($o->getSituation()->isError()){
       throw new Exception();
   }
}

function bar() {
   try {
      foo();
   } catch(Exception $e) {
      throw $e;
   }
}

try {
  bar();
} catch(Exception $e) {
  continue;
}

When will $o's destructor be called?

This all looks "funny" but nothing like a serious feature.

johannes

---

## #67188 — johannes@schlueters.de — 2013-04-29T07:45:23+00:00

URL: https://externals.io/message/67167#67188 · In reply to: #67184

> I agree with Amaury. 
> Although, it is rather smelly code to use try/catch as control flow
> instrument, in some situations it is clearer to do it this way. 
> I think the new construct would be especially useful if one just wants to
> log errors (no further exception handling is necessary) as shown in previous
> examples. 

Logging is a different thing from error handling. exceptions are a tool
to handle (exceptional critically?) error situations.

johannes

---

## #67189 — Lazare Inepologlou — 2013-04-29T08:13:11+00:00

URL: https://externals.io/message/67167#67189 · In reply to: #67185

2013/4/28 Julien Pauli <jpauli@php.net>

> On Sat, Apr 27, 2013 at 3:56 PM, Amaury Bouchard <amaury@amaury.net>
> wrote:
>
> > […]
> loop
> > […]
>
> "continue" is just a keyword (syntactic sugar) we sure can change, I like
> "resume" yes :-)
>
> Julien.Pauli
>


Does this sound familiar to anyone?

Sub Foo( Bar )
  On Error GoTo ErrorHandler
  . . .
  Exit Sub
ErrorHandler:
  . . .
  Resume Next
End Sub


:-)

Lazare INEPOLOGLOU
Ingénieur Logiciel

---

## #67191 — johannes@schlueters.de — 2013-04-29T15:12:27+00:00

URL: https://externals.io/message/67167#67191 · In reply to: #67190

> Hi Julien,
> 
> I'm still on the fence, not sure if it isn’t too opaque.
> 
> Am 26.04.2013 um 16:41 schrieb Julien Pauli <jpauli@php.net>:
> [...]
> 
> One question regarding scoping: does the next statement inherit the scope of the catch block like this?
> 
> try {
>    $user = $repository->findById(123);
>    $user->setName($name);
>    $em->save($user);
>    return true;
> } catch (NotFoundException $e) {
>    $user = new User();
>    continue;
> } catch (ValidationException $e) {
>    $user->setName($this->stripInvalidChars($name));
>    continue;
> } catch (PersistenceException $e) {
>    return false;
> }

In this specific case it would have to, as PHP has function-level
scoping, no block scoping.

But this really like abusing exceptions ...

johannes

---

## #67192 — ALeX — 2013-04-29T15:32:33+00:00

URL: https://externals.io/message/67167#67192 · In reply to: #67191

HI,

I also really don't like it.

if you have a try/catch within a for, will it continue the try or for?
(or have I to use "continue 2" to reach the for) At least use another
keyword to make it more clear that you don't want to continue a loop
at the beginning but a catch statement after the exception.

I would have solved your example like this:

try {
   try {
      $user = $repository->findById(123);
   } catch (NotFoundException $e) {
      $user = new User();
   }
   try {
      $user->setName($name);
   } catch (ValidationException $e) {
      $user->setName($this->stripInvalidChars($name));
   }
   $em->save($user);
   return true;
} catch (Exception $e) {
   return false;
}

I think that's more clear - but a few lines longer.

And it's probably more save, when the "$em->save($user);" throws a
NotFoundException exception then a new user will be created and then
(without saving) true is returned.

---

## #67193 — Ralph Schindler — 2013-04-29T15:43:55+00:00

URL: https://externals.io/message/67167#67193 · In reply to: #67167

> So, in this example, if, say, bar() throws a SomeException , the code
> would then resume and execute baz() after the catch block.
>
> Just presenting the idea here, no RFC actually , I'm collecting
> thoughts and notices.

It seems like you want application specific flow control (caller 
specific) when particular exceptions are raised.  This is achievable 
through goto, why not use that?

http://3v4l.org/HsdlD

<?php

class SomeException extends Exception {}

function foo() {
     echo 'attempting 1' . PHP_EOL;
}

function bar($someCondition) {
     echo 'attempting 2 with ' . $someCondition . PHP_EOL;
     if ($someCondition == null) {
         throw new SomeException('Foo foo fooey');
     }
}

function baz() {
     echo 'attempting 3' . PHP_EOL;
     throw new Exception('Boo boo bar');
}

function fixupforbar(&$someCondition) {
     $someCondition = 5;
}



/** main() **/


$someCondition = null;

try {
     foo();
     BAR: bar($someCondition);
     baz();
} catch (SomeException $e) {
     fixupforbar($someCondition);
     goto BAR;
} catch (Exception $e) {
     echo 'Exception caught: ' . $e->getMessage() . PHP_EOL;
} finally {
     echo 'Cleaning up' . PHP_EOL;
}




-ralph

---

Next page: https://externals.io/message/67167.md?page=2
