I have this C# code:
public object guardardinerohoy(float dinero,string comentario)
{
object dineromov1 = this.nuevodineromovimiento(dinero, variablesestaticas.usuarioglobal, DateTime.Now, null, claseenumeraciones.enumdineromovimiento.iniciosistema, comentario, DateTime .Now );
object resultado = "ok";
string abrirconexion = Conexion.conexion.abrirconexion();
if (dineromov1.GetType() != "".GetType() && abrirconexion == "ok")
try
{
Conexion.conexion.conect.AddTodineromovimiento((dineromovimiento)dineromov1);
Conexion.conexion.conect.SaveChanges();
return "ok";
}
catch (Exception ex)
{
resultado = ex.Message;
}
else
{
resultado = dineromov1.ToString() + abrirconexion;
return resultado;
}
}
I return "ok" if this saved successfully. Now when I checked if this was saved it was not. I do not understand why if it did not return an exception. This does not happen all the time. Sometimes it saves and sometime it does not.
I found this thread which says if it does not have exception, everything is ok.
Check if an insert or update was successful in Entity Framework
Entity Framework will throw an exception upon failure of Insert, Update or Delete.
Thus, you can assume with no exception that it's successful.
Related
I'm using WebDriverWait to get the value of a WebElement after some time, but if it doesn't change, I don't want it to fail, just get the current value and keep going with the execution.
I'm running a process in a Web that has a "process completed" label that I use to check if it finished. On the same screen there is an "elapsed time" for the process that I need to read to report how much time it took to run the process.
The issue is that there is a backend process running even after the "process completed" label appeared, and the time gets updated. I can't know how much time this "backend update" will take, and I don't know if in happy runs it can appear before mentioned label, for the moment, from my tests it goes from 10 to 40 seconds (60 to be sure).
We have a Waits class for this kind of stuff, but we didn't have a method for this text change validation, so I came up with this:
private static WebDriverWait _customWait(int value) => new WebDriverWait(
clock,
Driver.Instance,
TimeSpan.FromSeconds(value),
TimeSpan.FromMilliseconds(Settings.Timeouts.SleepIntervalInMillis));
public static void WaitForTextElementToChange(Func<IWebDriver, IWebElement> elementFinder, IWebDriver driver, int time)
{
string oldValue = elementFinder.Invoke(driver).Read();
_customWait(time).Until(drv =>
{
try
{
return !elementFinder.Invoke(driver).Read().Contains(oldValue);
}
catch (NotFoundException)
{
return true;
}
catch (StaleElementReferenceException)
{
return true;
}
});
}
This works. And I remark it because I don't fully understand yet the syntax and logic behind that Until method, I know that it gives a WebDriverTimeoutException and I left it that way to be an additional method for the framework.
So, if the value changes it gets out and keeps running lovely, but in this particular case, if it doesn't change, I don't need it to throw that exception so I called it within a try/catch.
Waits.WaitForProcessToFinish(drv => processCompleteLabel); //<- context code
try
{
//If value changes before 60 secs everything is fine
Waits.WaitForTextElementToChange(drv => timeElement, someDriverObject, 60);
//60 is a hardcoded int value just for testing
}
catch (WebDriverTimeoutException)
{
//But if it doesn't change just do nothing
}
string timeElapsed = timeElement.Read(); //<- context code
My question is, would it be ok to leave it that way?
What would you do instead?
Based on what I see in the source I don't think there is a way around this with how Until works.
The Until method executes a method passed to it in a loop until either a bool or object is returned or the timeout occurs.
public virtual TResult Until<TResult>(Func<T, TResult> condition)
{
if (condition == null)
{
throw new ArgumentNullException("condition", "condition cannot be null");
}
var resultType = typeof(TResult);
if ((resultType.IsValueType && resultType != typeof(bool)) || !typeof(object).IsAssignableFrom(resultType))
{
throw new ArgumentException("Can only wait on an object or boolean response, tried to use type: " + resultType.ToString(), "condition");
}
Exception lastException = null;
var endTime = this.clock.LaterBy(this.timeout);
while (true)
{
try
{
var result = condition(this.input);
if (resultType == typeof(bool))
{
var boolResult = result as bool?;
if (boolResult.HasValue && boolResult.Value)
{
return result;
}
}
else
{
if (result != null)
{
return result;
}
}
}
catch (Exception ex)
{
if (!this.IsIgnoredException(ex))
{
throw;
}
lastException = ex;
}
// Check the timeout after evaluating the function to ensure conditions
// with a zero timeout can succeed.
if (!this.clock.IsNowBefore(endTime))
{
string timeoutMessage = string.Format(CultureInfo.InvariantCulture, "Timed out after {0} seconds", this.timeout.TotalSeconds);
if (!string.IsNullOrEmpty(this.message))
{
timeoutMessage += ": " + this.message;
}
this.ThrowTimeoutException(timeoutMessage, lastException);
}
Thread.Sleep(this.sleepInterval);
}
}
What you're doing works, But I would suggest having your own timeout loop without using Wait.Until() since it's core function is to throw an exception if there is an issue.
I work with TFS API and now I need to show to user messages concerning to result from Workspace.CheckIn method.
public int? CheckInPendingChanges(PendingChange[] pendingChanges, string comments)
{
using (TfsTeamProjectCollection pc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(ConstTfsServerUri)))
{
if (pc == null) return null;
WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(ConstDefaultFlowsTfsPath);
Workspace workspace = workspaceInfo?.GetWorkspace(pc);
try
{
int? result = workspace?.CheckIn(pendingChanges, comments);
return result;
}
catch (CheckinException exception)
{
UIHelper.Instance.RunOnUiThread(() => MessageBox.Show(exception.Message, "Check in exception has happened", MessageBoxButton.OK, MessageBoxImage.Error));
return null;
}
catch (VersionControlException exception)
{
UIHelper.Instance.RunOnUiThread(() => MessageBox.Show(exception.Message, "Version Control Exception has happened", MessageBoxButton.OK, MessageBoxImage.Error));
return null;
}
}
}
However I haven't found comprehensive information about that. I've just found out that it should return changeset's ID in the case it has been succeed. In addition, I found this post:
https://blogs.msdn.microsoft.com/buckh/2006/09/18/vc-api-checkin-may-return-0/
It explains that CheckIn returns "0" if your files hasn't changes and TFS undone it.
But what does it means if it returns -1 and null?
Check Remarks of Workspace.CheckIn Method:
Each check-in is an atomic operation. All changes are checked in, or none are. If the check-in is successful, this method returns a positive changeset number. If the set of pending changes for the check-in is null, the server tries to check in all changes in the workspace. However, this operation is not valid if any pending changes in the workspace are edits or adds, because content will not have been uploaded to the server.
According to information that was gathered from different sources, I show to a user different messages:
public int? CheckInPendingChanges(PendingChange[] pendingChanges, string comments)
{
using (TfsTeamProjectCollection pc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(ConstTfsServerUri)))
{
if (pc == null) return null;
WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(ConstDefaultFlowsTfsPath);
Workspace workspace = workspaceInfo?.GetWorkspace(pc);
try
{
int? result = workspace?.CheckIn(pendingChanges, comments);
return result;
}
catch (CheckinException exception)
{
UIHelper.Instance.RunOnUiThread(() => MessageBox.Show(exception.Message, "Check in exception has happened", MessageBoxButton.OK, MessageBoxImage.Error));
return null;
}
catch (VersionControlException exception)
{
UIHelper.Instance.RunOnUiThread(() => MessageBox.Show(exception.Message, "Version Control Exception has happened", MessageBoxButton.OK, MessageBoxImage.Error));
return null;
}
}
}
1) If result is null or negative - I consider it as exception:
if (result < 0||result == null)
{
MessageBox.Show("Check in has failed due to internal Error", "Error", MessageBoxButton.OK,
MessageBoxImage.Error);
return;
}
2) If result is 0, I consider it as Undo has been executed:
if (0 == result)
{
MessageBox.Show("The version control server automatically undoed the pending changes due to attempt to check in files that haven’t changed.", "No changes have been detected in your check in", MessageBoxButton.OK,
MessageBoxImage.Information);
ChangeSourceControlOperation(SourceControlOperations.Undo, currentVm);
}
3). If result is positive, I consider that as successfull result from TFS:
if (result > 0)
{
//TODO: show changeset id or what ever
}
Correct me if I wrong.
I've been using azure table storage for years, and I'm not sure what the "proper" way to do this is with the newest WindowsAzure.Storage library, version 5.0.1-preview (for use in a new ASP.NET 5 application):
Problem:
Given a partition key and row key, delete the row without checking for existence first, and without failing if it does not exist.
Current Solution: This code works... but the exception handling is confusing:
public async Task DeleteRowAsync(CloudTable table, string partition, string row)
{
var entity = new DynamicTableEntity(partition, row);
entity.ETag = "*";
var op = TableOperation.Delete(entity);
try
{
await table.ExecuteAsync(op);
}
catch (Exception ex)
{
var result = RequestResult.TranslateFromExceptionMessage(ex.Message);
if (result == null || result.HttpStatusCode != 404)
throw ex;
}
}
Questions:
The exception itself pointed me to this TranslateFromExceptionMessage method... I can't find a whole lot of information on that and WrappedStorageException (the type of the exception that is thrown). Is this some kind of new/preferred way to check for 404 errors on storage exceptions? Does anyone know if all storage exceptions will now use this, or do I need to write code to test and figure it out?
There is an InnerException of type StorageException. Presumably our older code that used StorageException.RequestInformation.HttpStatusCode could access this inner exception in the same way. Is that "OK", or is parsing these new XML error messages better or more robust somehow?
Is there a different approach altogether that I should be considering for this case?
If you are using the latest client (Azure.Data.Tables), the delete method automatically swallows 404 responses and does not throw. This approach avoids the need to write code that introduces race conditions (checking first before performing an operations) or having to handle this condition with a try/catch block.
If you want to know if the operation actually deleted a table or it didn't exist, you can inspect the Status property of the response.
Response response = await tableClient.DeleteAsync();
if (response.Status == (int)HttpStatusCode.NotFound)
{
// entity didn't exist)
}
The RequestResult.TranslateFromExceptionMessage method is now marked [Obsolete] and I wanted a way to ignore 404's myself.
Based on your tip to check out the RequestInformation.HttpStatusCode I came up with the following:
try
{
await table.ExecuteAsync(op);
}
catch (StorageException storEx)
{
if (storEx.RequestInformation.HttpStatusCode != 404)
{
throw;
}
}
There is a similar approach found in the AspNet WebHooks project when configured to use Azure Table Storage. Take a look at the Microsoft.Aspnet.WebHooks.custom.AzureStorage StorageManager class.
I'm not sure this adds much on top of what you'd already found, but they handle everything without throwing an exception and always return a status code so you can react to that as necessary.
One difference here is they pass in the table and the operation to a multi-purpose ExecuteAsync method, rather than having one specifically for delete, but that's just an implementation detail.
Relevant code from their example:
public async Task<TableResult> ExecuteAsync(CloudTable table, TableOperation operation)
{
if (table == null)
{
throw new ArgumentNullException(nameof(table));
}
if (operation == null)
{
throw new ArgumentNullException(nameof(operation));
}
try
{
var result = await table.ExecuteAsync(operation);
return result;
}
catch (Exception ex)
{
var errorMessage = GetStorageErrorMessage(ex);
var statusCode = GetStorageStatusCode(ex);
var message = string.Format(CultureInfo.CurrentCulture, AzureStorageResources.StorageManager_OperationFailed, statusCode, errorMessage);
_logger.Error(message, ex);
return new TableResult { HttpStatusCode = statusCode };
}
}
public string GetStorageErrorMessage(Exception ex)
{
if (ex is StorageException storageException && storageException.RequestInformation != null)
{
var status = storageException.RequestInformation.HttpStatusMessage != null ?
storageException.RequestInformation.HttpStatusMessage + " " :
string.Empty;
var errorCode = storageException.RequestInformation.ExtendedErrorInformation != null ?
"(" + storageException.RequestInformation.ExtendedErrorInformation.ErrorMessage + ")" :
string.Empty;
return status + errorCode;
}
else if (ex != null)
{
return ex.Message;
}
return string.Empty;
}
public int GetStorageStatusCode(Exception ex)
{
return ex is StorageException se && se.RequestInformation != null ? se.RequestInformation.HttpStatusCode : 500;
}
The following code is causing an intermittent exception:
public int UnblockJob(int jobId)
{
using (var connect = MakeConnect())
{
var tag = connect.JobTag.SingleOrDefault(jt => jt.JobId == jobId && jt.Name == Metrics.TagNameItemBlockCaller);
if (tag == null)
{
return 0;
}
connect.JobTag.Remove(tag);
return connect.SaveChanges();
}
}
How can I correct or troubleshoot it?
From the documentation for DbUpdateConcurrencyException:
Exception thrown by DbContext when it was expected that SaveChanges for an entity would result in a database update but in fact no rows in the database were affected.
This means that the record you are attempting to delete has since been removed from the database. It would appear that you have another process that is deleting records or this function is able to be called concurrently.
There are several solutions, here are a couple:
Fix the source problem Stop other processes affecting the data.
Catch the error Wrap this method in a try/catch block, after all you may only care that the record has been deleted:
try
{
//Existing code here
}
catch(DbUpdateConcurrencyException)
{
//Safely ignore this exception
}
catch(Exception e)
{
//Something else has occurred
throw;
}
I am currently working with SQL on my C# asp.net page.
I insert a value into the Database, but then if the ID is duplicate I get this exception:
{"Violation of PRIMARY KEY constraint 'PK_Section'. Cannot insert duplicate key in object 'dbo.Section'.\r\nThe statement has been terminated."}
What I want to do is to treat the exception doing something like:
if(exception=={"Violation of PRIMARY KEY constraint 'PK_Section'. Cannot insert duplicate key in object 'dbo.Section'.\r\nThe statement has been terminated."})
//update values instead of insert
My problem is that I can't compare exception(which is a string) with that long "string" that I get from trying to duplicate the IDs.
Is there anyway that I can compare this so that I can properly work on a solution to this error?
You should catch the SqlException (which will probably be the InnerException of your exception) and check its Number property to identify the exception.
See http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlexception.number.aspx
I would use a try catch block to check for a SqlException. Something like this:
private bool SaveDocument()
{
bool saved = false;
try
{
Save();
saved = true;
}
catch (Exception ex)
{
string errorTitle = Resources.SaveErrorCaption;
string errorText = Resources.SaveErrorText;
Exception initialEx = ex;
while (ex.InnerException != null)
{
if (ex.InnerException is SqlException)
{
int errorNo = ((SqlException)ex.InnerException).Number;
if (errorNo == 2627)
{
errorTitle = Resources.DuplicateEntryErrorTitle;
errorText = Resources.DuplicateEntryErrorMessage;
}
}
ex = ex.InnerException;
}
MsgBox.Show(errorTitle, errorText,
string.Format("{0}{1}StackTrace:{1}{2}", initialEx.Message, Environment.NewLine, initialEx.StackTrace),
MsgBoxButtons.OK, MsgBoxImage.Error);
}
return saved;
}