Try Catch Throw

I am trying to understand how I am going to use Throw in my code. I have a MainForm class for handling Windows Form GUI, and then I have a Manager class for reading and saving data from / to files.

I use Try / Catch in both classes, but my instructor wants me to use Throw in the Manager class, and despite this, I read about it, I don’t understand what it will do? Will Throw affect Try / Catch in MainForm class?

I also use the message box in the manager class if the exception is caught, but no message box can be in the manager according to the instructor, so how will I do? Is it possible to use the message field only in the MainForm class? Provide some help to understand and expand my knowledge! Thanks!

MainForm Class:

try { motelManager.SaveToFile(file); } catch { MessageBox.Show("Ett fel uppstod!", "Varning!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } 

Manager Class:

  public void SaveToFile(string filePath) { try { string newFilePath = filePath.Replace(".bin", ""); filestream = new FileStream(newFilePath + ".bin", FileMode.Create); BinaryFormatter b = new BinaryFormatter(); b.Serialize(filestream, animals); } catch(Exception ex) { MessageBox.Show(ex.Message, "Varning!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } if (filestream != null) filestream.Close(); } 
+6
source share
7 answers

your manager class should look like this:

 public void SaveToFile(string filePath) { try { string newFilePath = filePath.Replace(".bin", ""); filestream = new FileStream(newFilePath + ".bin", FileMode.Create); BinaryFormatter b = new BinaryFormatter(); b.Serialize(filestream, animals); } catch(Exception ex) { if (filestream != null) filestream.Close(); throw; // but don't use // throw ex; // it throws everything same // except for the stacktrace } // or do it like this //catch(Exception ex) //{ // throw; // but don't use // throw ex; // it throws everything same // except for the stacktrace //} //finally //{ // if (filestream != null) filestream.Close(); //} } 

and in your main class:

 try { motelManager.SaveToFile(file); } catch (Exception e) { MessageBox.Show("Ett fel uppstod!", "Varning!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } 
+6
source
 public void SaveToFile(string filePath) { try { string newFilePath = filePath.Replace(".bin", ""); filestream = new FileStream(newFilePath + ".bin", FileMode.Create); BinaryFormatter b = new BinaryFormatter(); b.Serialize(filestream, animals); } catch (Exception ex) { if (filestream != null) filestream.Close(); //what you want //MessageBox.Show(ex.Message, "Warning!"); throw (new Exception("Your custom message")); } } 

And in your manager:

 try { manager.SaveToFile(filePath); } catch (Exception ex) { // here shows your 'Your custom message' MessageBox.Show(ex.Message); } 
+1
source

you can use Application ThreadException to catch any exception. And your save logic to migrate using instead of try catch, in which case it will close your stream.

 public void SaveToFile(string filePath) { string newFilePath = filePath.Replace(".bin", ""); using(var filestream = new FileStream(newFilePath + ".bin", FileMode.Create)) { BinaryFormatter b = new BinaryFormatter(); b.Serialize(filestream, animals); } } 

at the entry point (static void main ()) subscribe to this event.

  [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); Application.ThreadException += Application_ThreadException; } static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) { MessageBox.Show("......."); } 
+1
source

Throw just throws an exception for the calling function. (in this case, the one who calls SaveToFile). If there is an error handler there, it will be caught, otherwise it will continue to work on the call stack until it is caught or at the top level.

+1
source

It is better to handle Exception from the point of view of representing the user in the form - simply because on a larger well-structured system, the Manager object may not have any connection to the graphical interface.

The general rule is to catch the exception in the [Manager] backend server to clear any resources (ie close the file), and then throw the exception again from the exception handler as follows:

 public void SaveToFile(string filePath) { try { string newFilePath = filePath.Replace(".bin", ""); filestream = new FileStream(newFilePath + ".bin", FileMode.Create); BinaryFormatter b = new BinaryFormatter(); b.Serialize(filestream, animals); } catch(Exception ex) { /* * cleanup resources and rethrow the exception for catching and handling elsewhere */ if (filestream != null) filestream.Close(); throw; } } 
+1
source

In an application with multiple levels, exceptions that occur in the base layers are not sent to a higher level or to the calling application.

For example, if something goes wrong in the code associated with the database, you do not send it to the client application or to a higher level. The reason for this is to provide user friendly error messages. Let's say that during the delete operation you had reference errors of a foreign key, you can:

  • Record the exception information.
  • Replace it with a user-friendly exception message and move it to the layer above.

The layer above can wrap this exception with another message of a higher level, and then throw it forward. This is similar to what you were asked to do.

In your code in the Manager class, check how many exceptions can occur. If you use VS, the hint / hint text provides this information. If you are not using VS, check out MSDN for this information.

In the form, handle all exceptions that can be selected by the manager layer, as well as a general exception if something terrible happens. IMHO, this is how your code in the manager layer should like

 try { string newFilePath = filePath.Replace(".bin", ""); FileStream filestream = new FileStream(newFilePath + ".bin", FileMode.Create); BinaryFormatter b = new BinaryFormatter(); b.Serialize(filestream, animals); } catch (ArgumentNullException argNullException) { // Log current exception // Wrap it under your exception type CustomWrapException customWrap = new CustomWrapException(); customWrap.Message = "Your custom message here."; customWrap.InnerException = argNullException; throw customWrap; } catch (SecurityException securityException) { // Log current exception // Replace current exception with you custom exception CustomReplaceException replaceException = new CustomReplaceException(); replaceException.Message = "Your custom message here."; throw replaceException; } finally { // Close stream and dispose objects here } 

Your form must have exception handling, for example:

 try { // Call mananger code from here } catch (CustomWrapException wrapException) { // replace/wrap if desired // Display message to user } catch (CustomReplaceException replaceException) { // replace/wrap if desired // Display message to user } catch (Exception exception) { // This is for everything else that may go wrong apart from known possible exceptions // Display message to user } finally { } 

NTN.

+1
source

This is true...

  try { } catch(Exception e) { throw } 

When it throws an exception, it will change the trace of the source and the stack, so it will appear that the exception was selected from this method, from this very string throw e in the method containing this try-catch block.

0
source

Source: https://habr.com/ru/post/921652/


All Articles