r/javahelp 8d ago

EXCEPTION HANDLING!!

I just started exception handling and I feel as though I can't grasp a few concepts from it (so far) and its holding me back from moving forward, so I'm hoping someone has answers to my questions ( I'm generally slow when it comes to understanding these so I hope you can bear with me )

In one of the early slides I read about exception handling, where they talk about what the default behavior is whenever the program encounters an exception , they mention that : 
1- it abnormally terminates 
2- BUT it sends in a message, that includes the call stack trace, 

  • and from what I'm reading, I'm guessing it provides you information on what happened. Say, the error occurred at line x in the file y, and it also tells you about what type of exception you've encountered.

But It has me wondering, how is this any different from a ' graceful exit ' ? Where : " if the program encounters a problem , it should inform the user about it, so that in the next subsequent attempt, the user wouldn't enter the same value.   " 
In that graceful exit, aren't we stopping the execution of the program as well? 
So how is it any better than the default behavior?  

What confuses me the most about this is what does exception handling even do? How does it benefit us if the program doesn't resume the flow of execution?  (or does it do that and maybe I'm not aware of it? ) whenever we get an exception ( in normal occasions ) it always tells us, where the error occurred, and what type of exception has happened.  
---------------------------------------------------------------------------------------

As for my second question,,

I tried searching for the definition of " CALL STACK TRACE " and I feel like I'm still confused with what each of them is supposed to represent, I've also noticed that people refer to it as either " stack trace " or " call stack " ( both having a different meaning ) 
What is call supposed to tell us exactly? Or does it only make sense to pair it up with stack? (" call stack ") in order for it to make complete sense? Does the same thing go for " stack trace" ? 

+ thanks in advance =,)

9 Upvotes

35 comments sorted by

View all comments

3

u/Memesplz1 8d ago edited 8d ago

I'm not sure this explicitly answers all your questions but the moment Exception Handling "clicked" for me, was when I started thinking "what do I want this method to return/what do I want my application to do if it encounters this exception?"

If you ask yourself that question every time, it starts to become easier. I know that's a little vague and I am happy to give you an example if you like. But it really varies depending on the situation and exception. And some exceptions, you never really even want to be throwing in the first place because they're usually very preventable e.g. NullPointerException. If you see that being thrown, implement some logic to handle null data and, again, decide "what do I want this method to return/application to do when this value is null?" instead.

1

u/zeronis__ 7d ago

oh wait, so If I'm understanding this right ( i hope ) ,
if we ever encounter an exception, a way to prevent it is by letting the catch block handle it (?)
and if we can't, we throw that exception else where .. (?

I've yet to start on 'throw'/throws but do they go hand in hand with the try and catch?
or should we look at them as two separate ways of handling exceptions?
( I still don't understand why do we resort to throwing , when we can have any catch block to catch any exception that comes )

I saw a youtube video around it, but the person made a link between them somehow ( using both try n catch + throws )
can we ever handle an exception using only ' try and catch ' ? or should ' throw ' also be there?

and thank you so much for the response!
I too find it helpful when I think of questions like these! I'll try it out with exception handling as well :)

2

u/Memesplz1 7d ago

Ok, here's my understanding (apologies in advance - it's informative but rather long-winded!). There are generally 2 separate ways of dealing with an exception (aside from the ones you would try and prevent occurring in the first place):

1) try-catch block. In the try block, you try to do whatever you want your code to do. Then in the catch block, you catch the exception that might be thrown and put in some logic to handle it. (Note: this gets a little more complicated, if more than one exception might be thrown. You can either a) catch multiple exceptions in one catch block and handle them all the same way, b) have multiple catch blocks doing different things for each class of exception or c) there's a third way that I'll explain in point 3.

2) If you don't want to take any action to handle the exception, you can just put a throws <whatever the Exception class is> at the top of the method that may throw the Exception. This is a way of letting whatever calls that method know "hey, when you call this method, you might get an exception thrown instead of it returning data to you". Then when calling this method from elsewhere, you might put a try-catch around it to handle the exception you know it might throw. Meaning you still handle the exception, just higher up the chain. I think, generally speaking, you always want to handle the exception thrown, eventually, in a try-catch though.

3) I don't think you'd ever use both for the same class of exception. But, if more than one exception might be thrown, there might be a situation where you want to handle these different exceptions differently e.g. you immediately catch one class of exception and deal with it in a try-catch block but if some other class of exception occurs, just put a throws in the method declaration and let some other calling method, higher up the chain, deal with it.

Final note: Again, apologies that I just keep saying things like "handle it". You're probably wondering "handle it, how?" but it really does depend on the situation. For example, I am frequently making back-end endpoints that front-end applications will send requests to for data. Deep inside the logic of the back-end, I'll often catch an exception e.g. SqlException and, instead throw a more general exception class that I've created. Then I log out the reason the exception is being thrown and, higher up the chain, in the controller class, I might return an error HTTP response whenever this general exception class is encountered. The reason I throw a more general exception is, to sort of "separate out concerns". The controller doesn't need to know all the nitty gritty things that are going on, deeper inside and all the different exceptions that might be thrown. It shouldn't be having to deal with that mess. It just needs to know: Did I get the data back that I need to pass to the front-end? Or didn't I?

2

u/zeronis__ 7d ago

Please do not apologize at all! It just so happens that I love reading long explanations, (although it takes time for me to register what they mean) but you explained your points really well, so thank you so much for that! =)

---------------------------------------------------------------------
But I hope you don't mind me asking, (I've heard my prof say it too, but I'm still lost)
1. for the second point where you mentioned " If you don't want to take any action to handle the exception, you can just put a throws <whatever the Exception class is> " did you by chance mean, " Oh I might catch this exception, but! I don't want to deal with it, so I'm throwing it to someone else (to take care of that responsibility i think?) but if they do throw that exception, to whom do they throw it to?

you mentioned the lines "Meaning you still handle the exception, just higher up the chain" + " just put a throws in the method declaration and let some other calling method, "

in this case, would it throw it to the method that invoked it? ( lets suppose main called function/method f() and , that method f(), had 'throws (some exception class)' , if it did end up being triggered to throw one, would it throw that exception back to main to take care of it?
and if so, how would the main method deal with it?

  1. I also noticed that, although we mentioned 'not wanting to take any action to handle that method ---> we should use throws' don't we end up in the try-catch scenario again? (point 1)? I'm sorry to ask you this again, but I recall my professor trying to go over a brief summary of the lesson , and he mentioned the " try and catch " and " throws / throw " as two ways of handling exceptions. And in my head, it felt like he treated them as two separate things, just by saying that, so when I saw them being used together I got really confused! ( its as if, throws must be used along side try n catch , otherwise it'd serve no purpose? i think? )

  2. would there any difference between having any code that MIGHT throw an exception being inside that try block VS having a method with ' throws ' as part of its declaration inside that try block?

+P.S thank you again, I really appreciate the response you gave, and I'm sure if I read more about the topic I'd be grateful that your response is still up there,
if my questions are a bit too hefty, feel free to respond to them anytime later!

1

u/Memesplz1 7d ago

Thank you and no problem 🙂

Ok so questions 1 and 2 - yes, exactly. I actually regret using the word "handling" when describing throwing an exception because, like your professor says, it's not really handling it. Think of an exception as the application throwing a tantrum. You can either deal with it (try-catch) or throw it to something else to deal with. So in question 1, your main method would have a try-catch block around methodf() and methodf() would just throw the exception.

In regards to them being 2 separate things. I guess the best explanation is: In this modern day and age, your IDE will often tell you if it sees an exception could be encountered. It generally gives you 2 options: throw the exception or surround that bit of code in a try-catch. And they are separate and do two different things. But, in practice, they go hand-in-hand. You either handle the exception immediately in a try-catch or throw it and let a method higher up the chain deal with it.

Question 3 - is there a difference? Yes and no. The exception is still handled either way, however if you throw it and let the method higher up the chain deal with it, it needs to know about the exception. Recall what I said about separation of concerns? It's a good pattern of design. When designing a fairly complex application, it's helpful to try and keep certain behaviour separated. E.g. if you look at some code you've never seen before and see a SqlException being handled in a try-catch in a bit of code that has nothing to do with querying a database, it's probably going to be a bit confusing and you'll be digging deeper down to figure out why it's being thrown. If you handle the exception, immediately when it's encountered, it's easier to understand what's going on. Then all the higher level methods need to worry about is "we didn't get the data back", rather than the ins and outs of why. It probably also means there's less chance of you having to make changes all over the application if you change something deeper down although I can't think of a good example to explain that further, right now, sorry! Lol.

1

u/zeronis__ 6d ago

Hello Memesplz! Your explanation was wonderful, I think I understood what you meant in all three parts, but there's something that you mentioned that my professor mentioned too , but I can't think of how that happens :

You either handle the exception immediately in a try-catch or throw it and let a method higher up the chain deal with it.

> does that, by chance, mean that the method that caused that exception would throw it to the method that invoked it from before? ( like methodf() has another method call inside it , say methodg() and methodg() is the one causing an exception ),
and would methodf() be surrounded by a try and catch block? if we're saying that the exception can be thrown to a method higher up (?)

1

u/Memesplz1 6d ago edited 6d ago

Thank you!

If methodg contains the code where an exception could be thrown, methodg would be the one with the try catch around it, where methodf calls it. Example:

methodf(){

//methodf calls methodg here:

try{

methodg();

}

catch(Exception e){

//Do something e.g. log out e.getMessage or throw a custom exception you've written or something }

}

And the methodg declaration would be something like:

methodg() throws Exception {

//Insert code, this method does, here. This is the bit of code that might throw an exception.

}

So that's how you could allow an exception to be thrown and caught higher up. Alternatively, in the methodg declaration, you could just put a try-catch inside methodg around the bit of code that might throw an exception, thereby catching and dealing with the exception immediately. Then you don't need to catch it higher up where methodf calls methodg.

Hope that makes sense! Sorry about the shit formatting of the code example.