Reputation: 97
I have a nested Try/Catch for inventory's ins and outs.
If the Serial number is repeated, the inventory cannot be updated to sum the quantity entered.
Meaning: If I have product "X" with the Serial number "12345" and I enter that, the systems checks if within the "X" products the serial exists.
The first try inserts the serial number, the second try updates inventory.
F/E: I have 7 "X" products, among that 7 products is "12345". If I insert "12345" the first catch indicates that "12345" already exists, but before that updates the inventory and sums +1 to "X" products leaving 8 "X" products when that should not be.
Here's some code:
try
{
MySqlCommand cmdc = new MySqlCommand( "insert into mov ( folio, clave, descr, total, timo ) VALUES ( '"
+ textBox1.Text
+ "' ,'"
+ comboBox1.Text
+ "' ,'"
+ textBox3.Text
+ "' ,"
+ r1
+ ",'S');" ,
conn
) ;
MySqlDataAdapter dataadapc = new MySqlDataAdapter(cmdc);
System.Data.DataTable datatabc = new System.Data.DataTable();
dataadapc.Fill(datatabc);
foreach (DataRow row in datatabc.Rows)
{
string rows = string.Format("{0}", row.ItemArray[0]);
aux = rows;
}
try
{
MySqlCommand command = new MySqlCommand("update inventario SET can = can - "
+ numericUpDown1.Value
+ " WHERE cla = '"
+ comboBox1.Text
+ "';" ,
conn
) ;
command.ExecuteNonQuery();
j++;
}
catch (Exception ex)
{
MessageBox.Show("Error: No se puede modificar el inventario.");
MessageBox.Show(ex.Message);
}
try
{
MySqlCommand command = new MySqlCommand("update inventario SET lin = 'CMI', dias = 0 WHERE cla = '"
+ comboBox1.Text
+ "';" ,
conn
) ;
command.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show("Error: No se puede modificar el inventario.");
MessageBox.Show(ex.Message);
}
}
catch (Exception ex)
{
MessageBox.Show("Error: No se puede modificar el inventario.");
MessageBox.Show(ex.Message);
}
}
How can I stop the system if the 1st exception activates, so the 2nd query is not executed?
Upvotes: 0
Views: 579
Reputation: 31339
First off, you should use one try
block and one catch
block in your program to find and update a product.
That said, your code reveals many possible errors. You should use custom exceptions to navigate program flow after exceptions (not all exceptions should be/are handled the same way).
This means MySqlCommand
should throw meaningful exception that explain what the exception was, just like you name variables. For example, you can use name such as ProductNotFoundException
and UpdateProductException
.
you can do this be extending the class Exception
.
For instance, if you try to find the product and that fails, you can use a relevant "catch" clause and react accordingly. If you try to update the product and fail, you can react differently. Finally, a general exception (of type Exception) can be used to spot cases you didn't think of and report to you.
Consider this example:
try{
// try and find the product
MySqlCommand.findProduct(serial);
// if all is well, try and update the product
// not executed unless findProduct didn't throw an error
MySqlCommand.updateProduct(serial);
} catch (ProductNotFoundException pnfe){
// error while finding product
System.err.println("Product " + serial + " was not found!");
// .. code to handle product that does not exist
} catch (UpdateProductException upe){
// error while updating the product
System.err.println("Product " + serial + " could not be updated!");
// .. code to handle a failed product update
} catch (Exception e){
System.err.println("I have no idea why, but something went wrong!");
e.printStackTrace();
// handle a general exception
}
MySqlCommand
should look more like this:
public class MySqlCommand {
public void findProduct(int serial) throws ProductNotFoundException{
// .. code to find product
}
public void updateProduct(int serial) throws UpdateProductException{
// ... code to update product
}
}
And the ProductNotFoundException
class (UpdateProductException
is similar):
public class ProductNotFoundException extends Exception {
public ProductNotFoundException(String message){
super(message);
}
}
I also highly recommend reading about SQL Injection and how to prevent it in Java.
Learn more about exceptions, why and how they are used.
Upvotes: 0
Reputation: 343
I think you can define a flag that is initialized in each first try segment, and if an exception popped up in the first Catch, you can set that flag with a value (False for example) and in your second try, check that this flag is not set to the exception value (False)
bool foundException = false;
Try
{
// Reset the variable in the first Try
foundException = false;
}
Catch(Exception)
{
foundException = true;
}
End Try
Try
{
if(foundException)
{
break;
}
}
Catch(Exception)
{
}
Upvotes: 0
Reputation: 138
Include 2nd try-catch block into the end of first. This way 2nd block will be executed in case of first is successful.
try
{
//first
try
{
//secodn
}
catch
{
}
catch
{
}
Upvotes: 1
Reputation: 218887
How can I stop the system if the 1st exception activates, so the 2nd query is not executed?
By not using exceptions for control flow in the first place. The conditions you're checking for seem like valid things which could potentially happen. So use simple conditional expressions to check for them. You can nest those conditions accordingly.
So instead of this:
try
{
InsertID();
}
catch
{
// nothing exceptional happened
}
try
{
UpdateInventory();
}
catch
{
// this is a lot of try/catch for no reason
}
You would do something like this:
if (IDExists())
HandleIDExistsError();
InsertID();
UpdateInventory();
Or perhaps this:
if (!IDExists())
{
InsertID();
UpdateInventory();
}
Looking back at your updated question, you have a lot of try/catch blocks which are just handling logic flow. The catch
blocks are making assumptions about the nature of the error that occurred, which may be incorrect. And then they're throwing away useful information about the exception, which can be used to correct the problem.
Exceptions aren't for normal logic flow. Don't use them in place of conditionals.
Edit: Better yet, look into using transactions. Since you have two data modifications which should happen as a single atomic process, you might wrap that in an exception handler. Something like:
if (!IDExists())
{
try
{
BeginTransaction();
InsertID();
UpdateInventory();
CommitTransaction();
}
catch
{
HandleError();
RollBackTransaction();
}
}
Upvotes: 0
Reputation: 2353
Put a "return" in the catch, so that any code that follows will not be executed.
try
{
// Do something
}
catch
{
// Do something
return;
}
Upvotes: 0
Reputation: 16761
Put both actions in one try
block
try
{
MySqlCommand command = new MySqlCommand("update inventario SET can = can - " + numericUpDown1.Value + " WHERE cla = '" + comboBox1.Text + "';", conn);
command.ExecuteNonQuery();
j++;
MySqlCommand command = new MySqlCommand("update inventario SET lin = 'CMI', dias = 0 WHERE cla = '" + comboBox1.Text + "';", conn);
command.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show("Error: No se puede modificar el inventario.");
MessageBox.Show(ex.Message);
}
Upvotes: 4
Reputation: 2288
Can you do something like this:
try{
try{
// insert serial number
}
catch{
//handle exception
throw;
}
try{
// update inventory
}
catch{
// handle inventory exception
}
}
catch{
// handle other exceptions
}
Upvotes: 0
Reputation: 4328
From your description, I'm assuming you want an exception to keep travelling upwards.
You can do that by throwing the exception again
catch (Exception ex)
{
//Log the error or whatever
throw;
}
This will toss the exception upwards, and your second part of the code won't be executed.
Upvotes: 0