-1

I'm trying to figure out the best way to immediately exit a method from within another submethod inside of it. I know I can throw an exception BUT I already have a try catch inside that method that will catch any exception I throw. I'm basically attempting to do something twice, like ping a server, and if it fails the first time, catch the exception and try again, but if it fails the 2nd time, exit the entire method. is there an Initialize().Exit() I can implement? It doesn't seem like throwing an exception from an exception is the best way to do this. I want to catch if the initial ping fails or gets an error because sometimes the ping will fail and I have handling for attempting to connect to another server (not shown) if it does either of these.

public main()
{
    bool pingedOnce = false;
    try {
    Initialize();
    }
    catch (Exception e)
    {
        Console.WriteLine("e");
    }
}

public void Initialize()
{        
        try
        {

            if (new Ping().Send(server).Status == IPStatus.Success) //pings server to see if it exists
            {
                Console.WriteLine("Successfully Pinged " + server);
            }
            else
                throw new System.Exception();
        }
        catch (Exception e)
        {
            if (!pingedOnce)) //see if server has been pinged before
            {
                pingedOnce = True;
                Console.WriteLine("WARNING: failed to get data from server attempting to reconnect...");
                ReconnectToServer(server);
            }
            else
                throw new System.Exception("ERROR: Failed to connect to server after re-attempt.");
        }
}

Another example of a similar problem:

public Main()
{
    Initialize();
}
public void Initialize()
{
    foreach(string s in serverIPList)
    {
        for (int i=0; i<5; i++;)
        {
            if (new Ping().Send(serverIPList[i]).Status == IPStatus.Success) //when it finds a server that it successfully pings, it exits the method
                Initialize().Exit(); //I want this to exit this for loop, the foreach loop, and the initialize method entirely.
        }
    }
}

I could theoretically NOT choose to do a void method and just have it return null and never assign the method to anything, but is that a better practice than a nested try catch?

KRET1
  • 21
  • 2
  • Why not `return` from the method? – Frontear Nov 14 '19 at 14:15
  • I believe you may be looking for ```return;``` https://stackoverflow.com/questions/1283325/is-it-bad-practice-to-use-return-inside-a-void-method – Blaise Nov 14 '19 at 14:16
  • 1
    @Frontear - it sounds like they want to return from the method that called the current method. Which isn't possible with a simple `return`. – Broots Waymb Nov 14 '19 at 14:17
  • 1
    You shouldn't be using a try/catch to handle your 2nd ping if you're able to tell whether or not it was successful. Just check the status and either do try again or proceed. You could then return a true/false (or whatever you want, really) from the initialize method so that the called can make a decision on what to do next. – Broots Waymb Nov 14 '19 at 14:19
  • At least from the second example, there is no mention of wanting to explicitly return from the `Main` method. I think OP needs to clarify the issue a bit, as for the second example, a simple return or break would suffice – Frontear Nov 14 '19 at 14:19
  • 2
    Change your Initialize return type from void to bool and act accordingly in the main method. – Steve Nov 14 '19 at 14:21
  • 1
    @Frontear I would say that "exit a method from within another submethod" seems to indicate that. Although it does sound odd and I'm not sure that's what OP actually meant... – Code Stranger Nov 14 '19 at 14:22
  • This question is a bit too open ended for a simple solution, as evident with the different solutions already given. – Frontear Nov 14 '19 at 14:22

2 Answers2

2

If you want to stick with your exception handling design, you would be advised to create a custom class that derives from System.Exception. You should almost never throw a System.Exception; instead throw a more-specialized exception, and that enables you to catch and handle each type of exception differently. For example:

    try
    {
        // this can throw different kinds of exceptions.
    }
    catch (InvalidOperationException e)
    {
        // do something.
    }
    catch (ArgumentException e)
    {
        // do something different.
    }
rory.ap
  • 34,009
  • 10
  • 83
  • 174
  • Yup. First guideline [here](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/using-standard-exception-types) is to not throw System.Exception. – Broots Waymb Nov 14 '19 at 14:28
1

If you have exception throw. Else return!

if (new Ping().Send(server).Status == IPStatus.Success) //pings server to see if it exists
            {
                Console.WriteLine("Successfully Pinged " + server);
return; //RETURN here if you dont want to do anything!
            }
            else
                throw new System.Exception();

and do it same wherever. So you can catch exceptions if occurs or method will stop where you want.

wikiCan
  • 449
  • 3
  • 14
  • OP wants a solution **other** than exceptions. – Frontear Nov 14 '19 at 14:20
  • 2
    No @Frontear, that's not accurate, OP just doesn't know how to accomplish it properly with exceptions. – rory.ap Nov 14 '19 at 14:21
  • 1
    I agree that OP isn't asking for a non-Exception solution, but I do think the way it's being handled currently isn't great (they're essentially using the first try/catch to drive logic for the 2nd try). I don't see any overwhelming issue with throwing one if the retry fails. – Broots Waymb Nov 14 '19 at 14:24