C
C#3w ago
Anar

✅ Creditable usage for `goto`?

I don't think it needs further explanation, basically the goal is to catch any exceptions that might be thrown from inner functions that get called, but to also allow your own exceptions to be thrown when validation fails. Any thoughts? A)
public static int Method()
{
try
{
int meow = 26;

// ... other logic

if (meow == 12)
throw new MyException1();

if (meow == 21)
throw new MyException2();

if (meow == 126)
throw new MyException3();

return meow * 2;
}
catch (MyException1)
{
throw; // Allow mine
}
catch (MyException2)
{
throw; // Allow mine
}
catch (MyException3)
{
throw; // Allow mine
}
catch
{
// Handle gracefully
return 0;
}
}
public static int Method()
{
try
{
int meow = 26;

// ... other logic

if (meow == 12)
throw new MyException1();

if (meow == 21)
throw new MyException2();

if (meow == 126)
throw new MyException3();

return meow * 2;
}
catch (MyException1)
{
throw; // Allow mine
}
catch (MyException2)
{
throw; // Allow mine
}
catch (MyException3)
{
throw; // Allow mine
}
catch
{
// Handle gracefully
return 0;
}
}
B)
public static int Method()
{
try
{
int meow = 26;

// ... other logic

if (meow == 12)
goto error1;

if (meow == 21)
goto error2;

if (meow == 126)
goto error3;

return meow * 2;
}
catch
{
// Handle gracefully
return 0;
}

error1:
throw new MyException1();

error2:
throw new MyException2();

error3:
throw new MyException3();
}
public static int Method()
{
try
{
int meow = 26;

// ... other logic

if (meow == 12)
goto error1;

if (meow == 21)
goto error2;

if (meow == 126)
goto error3;

return meow * 2;
}
catch
{
// Handle gracefully
return 0;
}

error1:
throw new MyException1();

error2:
throw new MyException2();

error3:
throw new MyException3();
}
C)
public static int Method()
{
try
{
int meow = 26;

// ... other logic

if (meow == 12)
throw new MyException1();

if (meow == 21)
throw new MyException2();

if (meow == 126)
throw new MyException3();

return meow * 2;
}
catch (Exception e) when (e is not MyException1 and not MyException2 and not MyException3)
{
// Handle gracefully
return 0;
}
}
public static int Method()
{
try
{
int meow = 26;

// ... other logic

if (meow == 12)
throw new MyException1();

if (meow == 21)
throw new MyException2();

if (meow == 126)
throw new MyException3();

return meow * 2;
}
catch (Exception e) when (e is not MyException1 and not MyException2 and not MyException3)
{
// Handle gracefully
return 0;
}
}
36 Replies
Unknown User
Unknown User3w ago
Message Not Public
Sign In & Join Server To View
canton7
canton73w ago
Wat? No, custom exceptions are great I'd go with A. Yes B's more "clever" and takes fewer lines, but A's more consistent with what people are used to seeing
Anar
AnarOP3w ago
hold on, I totally forgot about the when clause
canton7
canton73w ago
I think when would make it harder to read
Anar
AnarOP3w ago
catch (Exception e) when (e is not MyException)
{
// Handle gracefully
return 0;
}
catch (Exception e) when (e is not MyException)
{
// Handle gracefully
return 0;
}
Like so?
Unknown User
Unknown User3w ago
Message Not Public
Sign In & Join Server To View
Anar
AnarOP3w ago
Pretty legit imo but what if there are more exceptions to be taken care of
canton7
canton73w ago
I like when for taking logic out of the body of the catch, but not for removing another catch altogether
Unknown User
Unknown User3w ago
Message Not Public
Sign In & Join Server To View
canton7
canton73w ago
This is hardy "complex things". This is bread-and-butter error handling
Anar
AnarOP3w ago
I added yours to the post
Unknown User
Unknown User3w ago
Message Not Public
Sign In & Join Server To View
Anar
AnarOP3w ago
catch (Exception e) when (e is not MyException1 and not MyException2 and not MyException3) :harold:
canton7
canton73w ago
Use base classes, properties, etc. catch (ValidationExceptionBase)
Anar
AnarOP3w ago
yup that does seem to solve most of the problems
canton7
canton73w ago
catch (ValidationExceptionBase e) when (e.IsRecoverable) or something etc
Anar
AnarOP3w ago
but in my real case, the other exceptions that need to be caught already inherit from the same base, and some of them I cannot even edit/change (they are not from my code base)
canton7
canton73w ago
catch (Exception e) when (e is IValidationException)
Anar
AnarOP3w ago
anything but goto? :catfine:
canton7
canton73w ago
It's not that goto is always horrible, it's that people aren't used to seeing it used, and don't know how to easily spot the common usage patterns Code should be obviously correct
Anar
AnarOP3w ago
right is there no permission to open a poll or something?
Unknown User
Unknown User3w ago
Message Not Public
Sign In & Join Server To View
Anar
AnarOP3w ago
:catderp: not really what I wanted but obviously the duck
Unknown User
Unknown User3w ago
Message Not Public
Sign In & Join Server To View
hamarb123
hamarb1233w ago
or use a base type / interface / etc., or do catch (Exception e) when (e is not (MyException1 or MyException2 or MyException3))
Anar
AnarOP3w ago
I now realize it is not a duck but something called "dodo" think I'm gonna go with the latter option too in the end
Unknown User
Unknown User3w ago
Message Not Public
Sign In & Join Server To View
MODiX
MODiX3w ago
If you have no further questions, please use /close to mark the forum thread as answered
Anar
AnarOP3w ago
I'll wait a couple hours in case somebody new hops in, gonna close it dw
hamarb123
hamarb1233w ago
i mean, my real opinion is a) don't throw exceptions you didn't need to start with, b) catching all exceptions & discarding like that is quite sus, c) i don't mind goto (but not convinced it's really needed here tbh)
canton7
canton73w ago
It's no different to calling a helper method which throws the exception
hamarb123
hamarb1233w ago
not that this really matters - but i mean, it is different - you wouldn't say if/goto is no different to an if/else, even when you can get the same IL from it
canton7
canton73w ago
I mean, putting the whole body of the try (or some significant subset) into a helper method What if throwing the exception needs a bunch of local state, which is only available at the point that the exception is thrown? Although, replace your enum with constructing (but not throwing) the exception, and that can work well I mean, if you had a method which called a bunch of other methods in a try, you wouldn't complain about one of those methods throwing an exception and you catching it. Inlining those methods directly into your try should make no difference
Anar
AnarOP3w ago
then I'd say: for a very short and simple case, C is better; but if some additional steps need to be executed for each exception type, then B. Snippet A looks awkward to me too (throw X -> catch X -> throw)
ティナ
ティナ3w ago
int Func(){
int ret;
try{ ret=Func2(); }
catch(RecoverableError e){ ret=100; }
/// let FatalError throw
try{ ret=Func3(ret); }
catch(RecoverableError e){ ret=100; }
return ret;
}
int Func(){
int ret;
try{ ret=Func2(); }
catch(RecoverableError e){ ret=100; }
/// let FatalError throw
try{ ret=Func3(ret); }
catch(RecoverableError e){ ret=100; }
return ret;
}
? i dont really think a single big try-catch box is good fit, cconsider:
public static int Method(){
try{
int meow = 26;
meow=Func(meow); // throw
// ... other logic
if (meow == 12)
throw new MyException1();
if (meow == 21)
throw new MyException2();
if (meow == 126)
throw new MyException3();
return meow * 2;
} catch (Exception e) when (e is not MyException1 and not MyException2 and not MyException3){
// Handle gracefully
return 0;
}
}
public static int Method(){
try{
int meow = 26;
meow=Func(meow); // throw
// ... other logic
if (meow == 12)
throw new MyException1();
if (meow == 21)
throw new MyException2();
if (meow == 126)
throw new MyException3();
return meow * 2;
} catch (Exception e) when (e is not MyException1 and not MyException2 and not MyException3){
// Handle gracefully
return 0;
}
}
which is the same as
public static int Method(){
int meow = 26;
try{
meow=Func(meow); // throw
}catch(Exception e){
return 0; // or other handling
goto Return0;
}
// ... other logic
if (meow == 12)
throw new MyException1();
if (meow == 21)
throw new MyException2();
if (meow == 126)
throw new MyException3();
return meow * 2;
Return0: return 0;
}
public static int Method(){
int meow = 26;
try{
meow=Func(meow); // throw
}catch(Exception e){
return 0; // or other handling
goto Return0;
}
// ... other logic
if (meow == 12)
throw new MyException1();
if (meow == 21)
throw new MyException2();
if (meow == 126)
throw new MyException3();
return meow * 2;
Return0: return 0;
}
Anar
AnarOP3w ago
I see what you mean splitting it into two try-catch blocks also solves the issue in my case thanks for all of your suggestions :)

Did you find this page helpful?