Hamster
Resident Rodent
- Joined
- Aug 22, 2006
- Messages
- 45,908
- Reaction score
- 18,407
Pass the buck design pattern
South Africa’s biggest forum. Discuss, discover, and connect with thousands of members.
Pass the buck design pattern
Replace it with "throw;" (i.e. remove the ex) so you at least keep the original stack trace. "throw ex;" resets it. Won't make much of a difference here but now you know.
Omg this could be on a t-shirt. Aaahaha.
It's just for testing really, it gives me the most direct answer to what is going on. I'll clean it up later.
No, clean it up now. There is no later. You are knowingly incurring technical debt. Even if you catch it at a higher level, you will still see the full exception and stack trace;
Don't catch an exception if you are not adding value. Adding value means logging the exception, translating to a user friendly msg etc etc. Or rolling back the transaction. Otherwise don't. Let it bubble up where you actually want to do something useful with it.
E.g.
StartTransaction();
try
{
DbStuff();
CommitTransaction();
}
catch
{
RollbackTransaction();
throw; // It is cheaper to rethrow than to throw a new exception.
}
You need to "try" after creating the transaction. This will enable you to avoid "if tx!= null then tx.Rollback()" in you catch block.
As it stands now you could throw a null pointer exception in you "catch" block. This could happen if for instance "conn.Open()" throws an exception.
Brain overload for me. I'm lost.
Because your transaction "tx" is initialized to null and not an actual transaction. If you have an exception before the conn.beginTransaction() you'll get another exception since the transaction "tx" is null.
Hope that made sense.
protected void executeInsertQuery(String _query, SqlParameter[] sqlParameter)
{
using (SqlConnection connection = new SqlConnection(base.ConnectionString))
{
connection.Open();
SqlCommand command = connection.CreateCommand();
SqlTransaction transaction;
transaction = connection.BeginTransaction();
command.Connection = connection;
command.Transaction = transaction;
if (sqlParameter != null)
{
command.Parameters.AddRange(sqlParameter);
}
try
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = _query;
command.ExecuteNonQuery();
transaction.Commit();
}
catch (Exception ex)
{
Console.WriteLine("Commit Exception Type: {0}", ex.GetType());
Console.WriteLine(" Message: {0}", ex.Message);
try
{
transaction.Rollback();
}
catch (Exception ex2)
{
Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
Console.WriteLine(" Message: {0}", ex2.Message);
}
}
}
}
This looks about the most straight forward way using transactions.
https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction.commit(v=vs.110).aspx
PHP:protected void executeInsertQuery(String _query, SqlParameter[] sqlParameter) { using (SqlConnection connection = new SqlConnection(base.ConnectionString)) { connection.Open(); SqlCommand command = connection.CreateCommand(); SqlTransaction transaction; transaction = connection.BeginTransaction(); command.Connection = connection; command.Transaction = transaction; if (sqlParameter != null) { command.Parameters.AddRange(sqlParameter); } try { command.CommandType = CommandType.StoredProcedure; command.CommandText = _query; command.ExecuteNonQuery(); transaction.Commit(); } catch (Exception ex) { Console.WriteLine("Commit Exception Type: {0}", ex.GetType()); Console.WriteLine(" Message: {0}", ex.Message); try { transaction.Rollback(); } catch (Exception ex2) { Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType()); Console.WriteLine(" Message: {0}", ex2.Message); } } } }
Why do you need to throw the exception?Why the nested try? Don't need it... Also you need to rethrow the original..
try
{
your stuff
}
catch
{
tx.rollback();
throw;
}
By this time Solarion does not know where to hold and where to let go. I think Spacerat is wrong, but if he is not then I'm confused as well.
SqlTransaction transaction;
try
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = _query;
command.ExecuteNonQuery();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
LoggError.Write(ex);
}
public static class LoggError
{
public static void Write(Exception exception)
{
string logFile = String.Empty;
StreamWriter logWriter;
try
{
logFile = ConfigurationManager.AppSettings["ErrorLog"].ToString();
if (File.Exists(logFile))
logWriter = File.AppendText(logFile);
else
logWriter = File.CreateText(logFile);
logWriter.WriteLine("=>" + DateTime.Now + " " + " An Error occured : " +
exception.StackTrace + " Message : " + exception.Message + "\n\n");
logWriter.Close();
throw exception;
}
catch (Exception e)
{
throw;
}
finally
{
}
}
}
[)roi(];19001178 said:@solarion; simple is always the goal, however loggers doesn't quite cover what's IMO missing from your code examples i.e. explicit management of state; the functions you've shared recently all e.g. return void; so how exactly are you keeping track of what's worked and what's failed.
It's fairly rare that functions are completely independent entities; and usually form a link in a process chain. Re-throwing the exceptions up the stack would be 1 way to track this, another would be through return values.
I'm getting there. At the moment is just crashes and burns. Error handling is an area I'm sorely lacking on. Newbie coder remember so at the moment I'm actually doing this to learn and when I fudge it up, I just keep at it until I get it right.
[)roi(];18998588 said:Never much liked the try {} catch {} approach; an either monad with bind is always more elegant.
var a = function1(arg1);
var b = function2(a)
....
var z = function27(y)
private static Result<Success, Failure> function1(InputType input) { }
private static Result<Success, Failure> function2(Result<Success, Failure> input) { }
// this is called as follows
var a = function1(inputValue)
.bind(function2)
.bind(function3)
.bind(function4);