Objectify 4 transactions - google-app-engine

With Objectify 4 I am trying to throw a controlled exception inside a transaction. As vrun() interface does not allow throwing exceptions, I have to catch it. I do it, and then I want to perform the rollback, but when the transaction finishes and it all fails (I think it is because it tries to do a commit), not even doing the rollback. How can I do it?
Thanks in advance!
Code example:
ofy().transact(new VoidWork() {
#Override
public void vrun() {
//do something
//...
//find someting wrong and want to throw an exception
try {
throw new MyException(); //throw the exception
} catch (MyException e) {
ofy().getTransaction().rollback(); //catch it and perform rollback
}
}
});
//an error occurs

Related

How to Implement Retry analyzer in try catch Block?

Below is my code after got the exception immediately it should trigger one more time for execution but didn't execute.Without try,catch it was executing but after keep the code in try and catch RetryAnalyzer is not working as expected please anyone help me how to implement RetryAnalyzer in try,catch block
#Test(priority=4,enabled=true,retryAnalyzer=RetryAnalyzer.class)
public void TC_04() throws InterruptedException
{
try
{
extent=new
ExtentReports("/Users/anakin/workspace/Reports/MKE.html");
Login_Objects.Switch_PB2U(driver).click();
String screenshot_path = Screenshot.createScreenshot(driver);
String image = log.addScreenCapture(screenshot_path);
log.log(LogStatus.PASS, "To Stocks",image);
extent.endTest(log);
driver.closeApp();
}
catch(Exception e)
{
String screenshot_path = Screenshot.createScreenshot(driver);
String image = log.addScreenCapture(screenshot_path);
log.log(LogStatus.FAIL, "Verify Suggest Stocks ", image);
extent.endTest(log);
}
}
Catching exception in your complete test code is a bad practice. Even as in your case you are capturing screenshot in case of failure, you should use listener than catching exception.
Since retry analyzer works for failed tests, and you are cathing exceptions and thus supressing the errors, it might give the impression that your test never failed and thus the retryAnalyzer is not working.
Solution : Move code in Exception to Listeners and remove unnecessary Exception handling.

WinForms exception interceptor

I'm using the ABP framework with WinForms and I need to identify the best way to intercept an exception and log this information.
My WinForms is a Multiple-Document Interface (MDI) application. I add a HandleException in Program.cs so that when the application throws an exception, I'm able to log it in the log file. But if I get an exception in an ApplicationService, this exception is handled by ABP and not thrown back to WinForms, and nothing is written in the log file.
Do I need to implement some interface to have the classic logging like MVC/Angular app?
UPDATE
I found that the problem is related to async operation. Usually I call:
await _service.GetProducts();
If an exception is thrown, the main thread does not intercept it. If I switch to:
AsyncHelper.RunSync(() => _service.GetProducts());
Then the main thread intercepts the error.
because the exception is thrown in another thread you have to handle unhandled exceptions of the application domain. insert the exception handler into the starting point of your application. for win forms i guess you can use program.cs
static class Program
{
[STAThread]
static void Main(string[] argv)
{
try
{
AppDomain.CurrentDomain.UnhandledException += (sender,e)
=> HandleException(e.ExceptionObject);
Application.ThreadException += (sender,e)
=> HandleException(e.Exception);
Application.Run(new MainWindow());
}
catch (Exception ex)
{
HandleException(ex);
}
}
static void HandleException(object exception) {
var ex= exception as Exception;
if (ex== null) {
ex= new NotSupportedException("Unhandled exception: " + exceptionObject.ToString());
}
//you can log exception here -> ex.ToString();
}
}
Ok after some invastigation and googling I found this MSDN explanation Asynchronous Programming - Async from the Start
Accoriding to this article I change my program start to move to async code.
I need to chage a little bit more because I'm on Mdi Form when open a inside form
Form1 childForm = Globals.Bootstrapper.IocManager.Resolve<Form1>();
childForm.MdiParent = this;
var formAsync = childForm.InitializeAsync();
FormExtension.HandleExceptions(formAsync);
childForm.Show();
I add the static class to intercept the error form Abp
public static async void HandleExceptions(Task task)
{
try
{
await Task.Yield(); //ensure this runs as a continuation
await task;
}
catch (Exception ex)
{
//deal with exception, either with message box
//or delegating to general exception handling logic you may have wired up
//e.g. to Application.ThreadException and AppDomain.UnhandledException
var log = Globals.Bootstrapper.IocManager.IocContainer.Resolve<ILogger>();
LogHelper.LogException(log, ex);
//Exception handling...
MessageBox.Show("Ops!" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
//Application.Exit();
}
}
Now my log file is populated in correct way

How can I handle all possible exceptions when I do a POST with EF6 / SQL Server 2012

I am using the following code in my controller when I submit a new entry:
// POST /api/Content/
public HttpResponseMessage PostContent(Content content)
{
try
{
content.ModifiedDate = DateTime.Now;
_uow.Contents.Add(content);
_uow.Commit();
var response = Request.CreateResponse<Content>(HttpStatusCode.Created, content);
return response;
}
catch (DbUpdateException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.Conflict, ex);
}
}
This only picks up DbUpdateExceptions so if there is another kind of exception then I think I need to handle it differently.
Can anyone suggest how I should handle other exceptions?
You can add several catch in a row going from the most particular to most general
try
{
content.ModifiedDate = DateTime.Now;
_uow.Contents.Add(content);
_uow.Commit();
var response = Request.CreateResponse<Content>(HttpStatusCode.Created, content);
return response;
}
catch (DbUpdateException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.Conflict, ex);
}
catch (Exception ex)
{
// do what you want
}
If we want to move from quick-and-dirty method to longer-but-safer, we may pass following steps:
Excapsulate data access in separate object and handle it's exceptions in it, passing to the outside world custom exceptions. You may decide to hide all data access exceptions under single custom exception.
(as #Massanu pointed) Concatenate handlers starting with most particular to most general. To react approprietely on different exceptions, do not use single catch (Exception ex) handler.
If something, actually, let unhandled, you may catch it in Application_Error method of global.asax: http://msdn.microsoft.com/ru-ru/library/24395wz3(v=vs.100).aspx
There is a good chapter about error handling in Code Complete book written by Steve Macconell: http://cc2e.com/

Duplex channel callback calls method that throws exception. Where does the execption go?

And how can I present it to the user?
This post : WCF Duplex: How to handle thrown exception in duplex Callback is very close to my scenario. And this post is useful for helping me re-establish the connection when the channel is faulted.
I have a Publishing application Pub, and a subscribing WPF application Sub. The Pub sends a message and the Sub has subscribed for a callback using a duplex channel.
Sub.ViewModel.ReactToChange(sender, e) tries to read some data, but is unable to and throws an exception.
DispatcherUnhandledException doesn't catch it (I didn't really expect it to.)
AppDomain.CurrentDomain.UnhandledException doesn't catch it (that does surprise me)
The end result is I have an application that is still running, and no exception message is shown to the user so they can correct the problem. Is there a way I can show that exception to the user?
This is a bit tricky, but the only way I've found. I hope this helps others.
The idea is to not let an exception get thrown, but instead create an UnhendledExceptionEventArg and pass it up to your UI layer. Here is some example code:
public class BuggySubscriber : IDisposable
{
public BuggySubscriber(string dataSourceName)
{
SyncContext = SynchronizationContext.Current;
Subscriber = new MockSubscriber(dataSourceName);
Subscriber.Refreshed += OnDataChanged;
}
public SynchronizationContext SyncContext { get; set; }
public event EventHandler<UnhandledExceptionEventArgs> ExceptionOccurred;
// Bouncing Exception Step 3
private void OnExceptionOccured(Exception ex)
{
var callback = new SendOrPostCallback(delegate
{
var handler = ExceptionOccurred;
if (!ReferenceEquals(handler, null))
handler(this, new UnhandledExceptionEventArgs(ex, true));
});
SyncContext.Post(callback, null);
}
void OnDataChanged(object sender, ServiceModel.DataChanged.DataChangedEventArgs e)
{
// Bouncing Exception Step 1 & 2
OnExceptionOccured(new NotImplementedException());
}
So this is the "Sub" code. In the WPF application I add the following when the app starts:
protected override void OnStartup(StartupEventArgs e)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
BuggySubscriber.ExceptionOccurred += Sub_ExceptionOccurred;
...
}
// Bouncing Exception Step 5
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var exception = e.ExceptionObject as Exception;
if (!ReferenceEquals(exception, null))
ShowErrorMessage(exception);
}
// Bouncing Exception Step 4
void Sub_ExceptionOccurred(object sender, UnhandledExceptionEventArgs e)
{
var exception = e.ExceptionObject as Exception;
if (!ReferenceEquals(exception, null))
throw exception;
}
So now let's try to follow the bouncing exception.
In real life, the subscriber was notified and an exception occurs and is caught. (In my sample, I don't show that.)
Then the OnExceptionOccurred(Exception ex) is called.
That then creates the SendOrPostCallback using the ExceptionOccurred event and then does a Post to the current SynchronizationContext.
The WPF application that registered for the ExceptionOccurred (Now if you like, you could handle the exception message here... I chose to use two paths for exceptions rather than three.) It casts and throws the Exception.
Now the CurrentDomain_UnhandledException processes it and shows an error message to the user (right before it exits).
I'm sure there are many variations on this, but this does show some of the trickier code that I could not find in one place.
NOTE: This does not solve any channel problems. If you have an exception you can recover from you will still need to reestablish the channel since it will be faulted or closed.

ZombieCheck Exception - This SqlTransaction has completed; it is no longer usable -- during simple commit

I have the following code which performs a commit of a single row to a database table (SQL 2008 / .NET 4)
using (var db = new MyDbDataContext(_dbConnectionString))
{
Action action = new Action();
db.Actions.InsertOnSubmit(dbAction);
db.SubmitChanges();
}
Normally everything is fine, but once in a while I get the following exception:
System.InvalidOperationException: This SqlTransaction has completed; it is no longer usable.
at System.Data.SqlClient.SqlTransaction.ZombieCheck()
at System.Data.SqlClient.SqlTransaction.Rollback()
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
There are a number of similar questions on SO but I after reading them I cannot work out the cause.
Could this be simply due to a SQL timeout (the exception occurs close to 25s after the call is made)? Or should I expect a SQL timeout exception in that case?
Does anyone know what else may cause this?
The DataContext.SubmitChanges method has the following code lines in it's body:
// ...
try
{
if (this.provider.Connection.State == ConnectionState.Open)
{
this.provider.ClearConnection();
}
if (this.provider.Connection.State == ConnectionState.Closed)
{
this.provider.Connection.Open();
flag = true;
}
dbTransaction = this.provider.Connection.BeginTransaction(IsolationLevel.ReadCommitted);
this.provider.Transaction = dbTransaction;
new ChangeProcessor(this.services, this).SubmitChanges(failureMode);
this.AcceptChanges();
this.provider.ClearConnection();
dbTransaction.Commit();
}
catch
{
if (dbTransaction != null)
{
dbTransaction.Rollback();
}
throw;
}
// ...
When the connection times out, the catch block is executed and the dbTransaction.Rollback(); line will throw a InvalidOperationException.
If you had control over the code, you could catch the exception like this:
catch
{
// Attempt to roll back the transaction.
try
{
if (dbTransaction != null)
{
dbTransaction.Rollback();
}
}
catch (Exception ex2)
{
// This catch block will handle any errors that may have occurred
// on the server that would cause the rollback to fail, such as
// a closed connection.
Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
Console.WriteLine(" Message: {0}", ex2.Message);
}
throw;
}
YES! I had the same issue. The scary answer is that SQLServer sometimes rolls back a transaction on the server side when it encounters an error, and does not pass the error back to the client. YIKES!
Look on the Google Group microsoft.public.dotnet.framework.adonet for "SqlTransaction.ZombieCheck error" Colberd Zhou [MSFT] explains it very well.
and see aef123's comment on this SO post
May I suggest that connection closes earlier that transaction commits. Then the transaction is rolled back. Check this article on MSDN Blog.

Resources