Jump to page: 1 25  
Page
Thread overview
Rethrow an exception like in C++?
Mar 08, 2013
Rob T
Mar 08, 2013
Andrej Mitrovic
Mar 08, 2013
Rob T
Mar 08, 2013
Maxim Fomin
Mar 08, 2013
Rob T
Mar 08, 2013
Jonathan M Davis
Mar 08, 2013
Rob T
Mar 08, 2013
Jonathan M Davis
Mar 08, 2013
Chris Cain
Mar 08, 2013
Jonathan M Davis
Mar 08, 2013
Rob T
Mar 08, 2013
Jonathan M Davis
Mar 08, 2013
Rob T
Mar 08, 2013
Jonathan M Davis
Mar 08, 2013
Rob T
Mar 08, 2013
Jonathan M Davis
Mar 08, 2013
Andrej Mitrovic
Mar 08, 2013
Rob T
Mar 08, 2013
Ali Çehreli
Mar 08, 2013
Rob T
Mar 08, 2013
Ali Çehreli
Mar 11, 2013
Rob T
Mar 11, 2013
Rob T
Mar 11, 2013
Ali Çehreli
Mar 11, 2013
Rob T
Mar 08, 2013
Rob T
Mar 08, 2013
H. S. Teoh
Mar 08, 2013
Rob T
Mar 08, 2013
Jonathan M Davis
Mar 08, 2013
Rob T
Mar 08, 2013
Andrej Mitrovic
Mar 11, 2013
Rob T
Mar 08, 2013
Maxim Fomin
Mar 08, 2013
Jonathan M Davis
Mar 08, 2013
Jonathan M Davis
Mar 08, 2013
Rob T
Mar 08, 2013
Rob T
Mar 08, 2013
Jacob Carlborg
Mar 08, 2013
Rob T
Mar 08, 2013
Jonathan M Davis
Mar 08, 2013
Jonathan M Davis
March 08, 2013
In C++, I rethrow an exception without explicitly catching it

catch(...)
{
   throw;
}

Anyone know of a way to do the same thing in D?

catch
{
   // rethrow?

}

--rt
March 08, 2013
On 3/8/13, Rob T <alanb@ucora.com> wrote:
> In C++, I rethrow an exception without explicitly catching it
>
> catch(...)
> {
>     throw;
> }
>
> Anyone know of a way to do the same thing in D?
>
> catch
> {
>     // rethrow?
>
> }

The only way:

try { }
catch (Exception ex) { throw ex; }

Or use Error or Throwable if really necessary, however you shouldn't really catch those in normal code.
March 08, 2013
On Friday, 8 March 2013 at 01:56:45 UTC, Andrej Mitrovic wrote:
> On 3/8/13, Rob T <alanb@ucora.com> wrote:
>> In C++, I rethrow an exception without explicitly catching it
>>
>> catch(...)
>> {
>>     throw;
>> }
>>
>> Anyone know of a way to do the same thing in D?
>>
>> catch
>> {
>>     // rethrow?
>>
>> }
>
> The only way:
>
> try { }
> catch (Exception ex) { throw ex; }
>
> Or use Error or Throwable if really necessary, however you shouldn't
> really catch those in normal code.

That's very unfortunate, and should be corrected, because it means that you cannot easily catch multiple derived Exception types and rethrow the same derived type. Instead you have to explicitly catch all derived types and rethrow them individually, but that's simply not practical, so you end up catching only the base exception (Throwable?) and rethrow it, but you lose the derived type in the process.

--rt
March 08, 2013
On Friday, 8 March 2013 at 05:46:48 UTC, Rob T wrote:
> That's very unfortunate, and should be corrected, because it means that you cannot easily catch multiple derived Exception types and rethrow the same derived type. Instead you have to explicitly catch all derived types and rethrow them individually, but that's simply not practical, so you end up catching only the base exception (Throwable?) and rethrow it, but you lose the derived type in the process.
>
> --rt

Actually no.

class myException1 : Exception { this() { super("1"); } }
class myException2 : Exception { this() { super("2"); } }

void foo(bool val)
{
    if (val)
        throw new myException1;
    else
        throw new myException2;
}
void bar(bool val)
{
    try {
        foo(val);
    }
    catch (Exception e) {
        if (typeid(e) == typeid(myException1))
            throw e; // may be downcasted, if necessary
                     // to work with specific fields
    }
}


void main()
{
    try {
        bar(true);
    }
    catch (myException1 e) {}
    bar(false);
}
March 08, 2013
On Friday, March 08, 2013 06:46:47 Rob T wrote:
> That's very unfortunate, and should be corrected, because it means that you cannot easily catch multiple derived Exception types and rethrow the same derived type. Instead you have to explicitly catch all derived types and rethrow them individually, but that's simply not practical, so you end up catching only the base exception (Throwable?) and rethrow it, but you lose the derived type in the process.

No you don't. It doesn't matter what the type you catch with, since Exceptions are classes, they retain their original type when they're caught using a base class, and when they're rethrown. And the only reason that you'd lose the derived type in C++ doing exactly the same thing that you'd do in D would be because you were ignorant enough to catch by value rather than reference (which arguably shouldn't even be legal given the various hazards in doing so).

C++ has no exception capabilities that D doesn't have. If you truly want to catch _everything_ and then rethrow it, then just do

try {...}
catch(Throwable t)
{
    ...
    throw t;
}

But you should never catch Throwable or Error unless you know what you're doing. Exceptions that are meant to be caught are derived from Exception. So, it would be _far_ better to do

try {...}
catch(Exception e)
{
    ...
    throw e;
}

But if all you're going to do is rethrow it, and you don't care about the exception's type, then you should just use a scope statement:

scope(failure) ...

- Jonathan M Davis
March 08, 2013
On Friday, 8 March 2013 at 06:05:02 UTC, Maxim Fomin wrote:
>
> Actually no.
>
> class myException1 : Exception { this() { super("1"); } }
> class myException2 : Exception { this() { super("2"); } }
>
[...]

Thanks! That solves 99% of my problem. I wasn't aware that I could check the derived type from a base class reference like that.

The only remaining 1% is that I have a bit more boiler plate code for my catch, because I still have to always explicitly catch something otherwise I cannot )for example) write a function to get the exception and perform work on it and then rethrow. Instead I have to

catch( Exception E )
{
   throw dostuff( E );
}

in C++ I could do simply this

catch(...)
{
   // do stuff could get the exception on its own
   throw dostuff();
}


Seems trivial, but over hundreds of functions it becomes more of a significant productivity issue.

I can live with it, but I still think D could use an ability to rethrow whatever was the last exception with having to explicitly catch it.

--rt
March 08, 2013
On Friday, 8 March 2013 at 06:09:48 UTC, Jonathan M Davis wrote:
[...]
> C++ has no exception capabilities that D doesn't have.

Except that D cannot rethrow without explicitly catching. That may seem like a very minor item, but as I explained in my last post, the extra boiler plate coding can add up on larger sized projects.

Anyway, I got enough of my problem solved to move on, so I'm back to being very happy with D.

Thanks for the help!

--rt
March 08, 2013
One more thing, we finally got __FUNCTION__ (and more) added to MASTER so that's another missing item that was sorely missed. Now we can easily log what functions are catching and throwing exceptions, and more.

The big question is if Throwable will be expanded to automatically capture the function signature (as it does with line and file)? I hope there are no major concerns over legacy code breakage and it gets added in.

--rt
March 08, 2013
On Friday, March 08, 2013 08:08:48 Rob T wrote:
> On Friday, 8 March 2013 at 06:05:02 UTC, Maxim Fomin wrote:
> > Actually no.
> > 
> > class myException1 : Exception { this() { super("1"); } }
> > class myException2 : Exception { this() { super("2"); } }
> 
> [...]
> 
> Thanks! That solves 99% of my problem. I wasn't aware that I could check the derived type from a base class reference like that.
> 
> The only remaining 1% is that I have a bit more boiler plate code for my catch, because I still have to always explicitly catch something otherwise I cannot )for example) write a function to get the exception and perform work on it and then rethrow. Instead I have to
> 
> catch( Exception E )
> {
>     throw dostuff( E );
> }
> 
> in C++ I could do simply this
> 
> catch(...)
> {
>     // do stuff could get the exception on its own
>     throw dostuff();
> }

Then you can clearly do something here in C++ that I don't understand, because I have absolutely no idea how you could do anything the exception if you did catch(...), because there's no variable to work with.

Also, seeing as how the only difference between the two examples is that in the first case, the exception is passed to be thrown and the second it's thrown without its name, I don't see any functional difference between the two. So, I must be missing something here.

- Jonathan M Davis
March 08, 2013
On Friday, 8 March 2013 at 07:58:42 UTC, Jonathan M Davis wrote:
[...]
> Then you can clearly do something here in C++ that I don't understand, because
> I have absolutely no idea how you could do anything the exception if you did
> catch(...), because there's no variable to work with.
>

Check this out ...

In C++ you can do this

std::exception Trace()
{
   try
   {
      // key item missing from D
      throw; // <= rethrow last exception
   }
   catch( EType1 &E )
   {
       // do stuff
       return new std::exception( ...
   }
   catch( EType2 &E )
   {
       // do different stuff
       return new std::exception( ...
   }
   catch(...)
   {
       // unkown type, do something else
       throw new std::exception( ...
   }

}


void Foo()
{
   try
   {
      // For example only, I'd never do this!
      throw 10;
   }
   // I don't want to bother with what was
   // caught because I really don't need to know
   // so I catch whatever it may be.
   catch(...)
   {
      // I let Trace figure it all out.
      throw Trace();
   }

   return;
}

int main()
{
   try
   {
      Foo();
   }
   catch( std::exception E )
   {
       std::cout << E.what();
   }

   return 0;
}

In D, I have to explicitly catch and paste the exception reference to the function, and that is extra work that could be avoided if D could rethrow in a blanket catch block.

Eg,

catch // I don't care what I caught
{
   // If Trace could rethrow it could figure out what
   // was thrown and how to deal with it.
   throw Trace();
}

Instead I have to always do this

catch( Exception E )
{
   throw Trace( E );
}

That's OK for 20 try catch but specifying catch(Exception E) over and over adds up when you have to write a lot more of those. Copy paste helps, but not always.

--rt
« First   ‹ Prev
1 2 3 4 5