I have a controller where I need to invalidate a token and create a new token.
The controller code snapshot looks something like this:
function __regenerate_token($t)
{
if($token = Token::find()->where('token = :t' , ['t'=>$t])->one())
{
$token->expired = true;
$token->save(); // ->save(false);
}
$newtoken = new Token();
$newtoken->attributes = [
'token'=> strtolower(trim(\com_create_guid(), '{}')),
'expiry_at' => strtotime("+10 minutes"),
];
$newtoken->save(false);
return $newtoken;
}
Now whats happening is - update() also returns true & no errors. Same with insert. Individually run, they work fine. But if I call them they way it is - it fails silently.
The underlying table is innoDB. I tried to wrap the update & insert inside a transaction, but same issue.
Regard
I found out the reason. I was calling __regenerate_token in a function after a db-transaction. However in certain condition, the execution exited the function before committing / rolling back the changes. This caused the __regenerate_token also become part of the transaction and failed.
pseudo code
function debit_account
begin transaction
try
do stuff
if some_condition
return false #<-- this caused issue
endif
commit
return true
catch
rollback
return false
end function
debit_account()
__regenerate_token() #fails when some_condition is hit
Hope this someone else who hits a problem like this!
Related
I am trying to assert that, when I mouseover a covered element, the element on top is activated and not the hidden one.
However, when using .trigger('mouseover') on the hidden object, an error occurs because I cannot mouseover that object, and the test stops.
Is there a way to try to mouseover and assert that a failure occurs?
Your best bet for now is probably to use this .shouldNotBeClickable() command, because if the element cannot be clicked then it also cannot be hovered. Use this command with caution, as it skips all remaining commands in your it() block when used due to a bug in Cypress.
As of right now (Cypress 3.1.0), this is not possible. It should be as per this answer, but cy.once() has some code-breaking bugs that I've run into trying to adapt the command in that answer.
The following custom command does not work as of Cypress 3.1.0. It should work, but it causes Cypress to hang.
index.js:
Cypress.Commands.add("shouldNotBeHoverable", {
prevSubject: true
}, function(subject) {
let errorMessage = "shouldNotBeHoverable: element hover succeeded, but it souldn't have";
let done = false;
cy.wrap(subject[0]).trigger('mouseover', { force: true });
cy.once('fail', (err) => {
if (err == errorMessage)
throw errorMessage;
expect(err.message).to.include('cy.trigger() failed because this element');
expect(err.message).to.include('is being covered by another element');
done = true;
});
cy.wrap(subject[0]).trigger('mouseover', {timeout: 1000});
cy.get('html').then(() => {
if (!done)
throw errorMessage;
});
});
Cypress test:
cy.get("#selector").shouldNotBeHoverable();
The related Github issues are linked below. This specific issue isn't reported, but both issues are similar enough that I suspect the underlying cause is the same.
Mixing cy.on()/cy.once() with a one-argument it() function causes test to hang
Queued commands silently skipped when using cy.once() in a custom command
I have a loop which loops through connections. Each loop connects to a different connection and then loads tables and such. In the 2nd step is where it connects and then loads data into our DWH. Sometimes the connection is down for what ever reason and will fail at this step. I need the package to keep going on this connection fail.
I have read many things on the propogate set to false and this still does not work. As you can see in my screen shot, i have the "Load ..." onError event handler propogate set to false, and the Sequence container onError propogate set to false.
I have also tried setting the sequence container max errors to 0 so that section completes, and on the onError of the "Load ..." to set a flag in a variable to continue going if the connection completes, or stop there if the connection fails.
I have done this in the past and just set the overall package complete status to success on completion, but this will not catch other errors that may occur in this loop that I will need to catch / fail the package on.
Any help here would be appreciated.
Doing more research on connections failing, I found a script by Jamie Thomson: Verify a connection before using it [SSIS].
I modified it a bit to my own usage:
Only used a single connection instead of looping through all of them.
I set the task result to always succeed.
Instead of FireError I did a FireWarning.
I created a variable (connFail) to set to a 0 or a 1 depending on if the connection failed or not.
I places this script task before my table load to catch any failed connections before the task was executed. These modifications allowed me to fire an e-mail alert if the connection failed (connfail = 1), or continue on the package if the connection was successful (`connFail = 0').
Full script I used is below:
bool failure = false;
bool fireAgain = true;
try
{
Dts.Connections["Connection"].AcquireConnection(null);
Dts.Events.FireInformation(1, ""
, String.Format("Connection aquired successfully on '{0}'", Dts.Connections["Connection"].Name)
, "", 0, ref fireAgain);
}
catch (Exception e)
{
Dts.Events.FireWarning(-1, ""
, String.Format("Failed to aquire connection to '{0}'. Error Message='{1}'",Dts.Connections["Connection"].Name, e.Message)
, "", 0);
failure = true;
}
if (failure)
{
Dts.TaskResult = (int)ScriptResults.Success;
Dts.Variables["connFail"].Value = 1;
}
else
{
Dts.TaskResult = (int)ScriptResults.Success;
Dts.Variables["connFail"].Value = 0;
}
I have the following code in my background script. I send a message to another app, but if it fails, this gets called twice (note: my callback is called twice. My code calling sendMessage is only called once)!
chrome.runtime.sendMessage(
otherAppId,
someObject,
function (response)
{
var lastError = chrome.runtime.lastError;
//This likely means it doesn't exist ("Could not establish connection. Receiving end does not exist.")
if ( lastError && lastError.message.indexOf( "not exist" ) !== -1 )
{
///This gets called twice!
console.log( "we're here twice?!" );
}
//This is called once
else console.log( "Was successful, so called only once" );
}
);
Is there a way to cancel it so it stops trying again? Why does an error result in two calls to my callback?
I was defining my own Function.prototype.bind (in a JS library I'd included) and this caused the issue! No idea why this causes so many errors and causes the callback to fire twice but removing that makes all the errors go away!
When using the Background Transfer API we must iterate through current data transfers to start them again ahen the App restarts after a termination (i.e. system shutdown). To get progress information and to be able to cancel the data transfers they must be attached using AttachAsync.
My problem is that AttachAsync only returns when the data transfer is finished. That makes sense in some scenarios. But when having multiple data transfers the next transfer in the list would not be started until the currently attached is finished. My solution to this problem was to handle the Task that AttachAsync().AsTask() returns in the classic way (not use await but continuations):
IReadOnlyList<DownloadOperation> currentDownloads =
await BackgroundDownloader.GetCurrentDownloadsAsync();
foreach (var downloadOperation in currentDownloads)
{
Task task = downloadOperation.AttachAsync().AsTask();
DownloadOperation operation = downloadOperation;
task.ContinueWith(_ =>
{
// Handle success
...
}, CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion,
TaskScheduler.FromCurrentSynchronizationContext());
task.ContinueWith(_ =>
{
// Handle cancellation
...
}, CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled,
TaskScheduler.FromCurrentSynchronizationContext());
task.ContinueWith(t =>
{
// Handle errors
...
}, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted,
TaskScheduler.FromCurrentSynchronizationContext());
}
It kind of works (in the actual code I add the downloads to a ListBox). The loop iterates through all downloads and executes StartAsync. But the downloads are not really started all at the same time. Only one is runninng at a time and only if it finishes the next one continues.
Any solution for this problem?
The whole point of Task is to allow you to have the option of parallel operations. If you await then you are telling the code to serialize the operations; if you don't await, then you are telling the code to parallelize.
What you can do is add each download task to a list, telling the code to parallelize. You can then wait for tasks to finish, one by one.
How about something like:
IReadOnlyList<DownloadOperation> currentDownloads =
await BackgroundDownloader.GetCurrentDownloadsAsync();
if (currentDownloads.Count > 0)
{
List<Task<DownloadOperation>> tasks = new List<Task<DownloadOperation>>();
foreach (DownloadOperation downloadOperation in currentDownloads)
{
// Attach progress and completion handlers without waiting for completion
tasks.Add(downloadOperation.AttachAsync().AsTask());
}
while (tasks.Count > 0)
{
// wait for ANY download task to finish
Task<DownloadOperation> task = await Task.WhenAny<DownloadOperation>(tasks);
tasks.Remove(task);
// process the completed task...
if (task.IsCanceled)
{
// handle cancel
}
else if (task.IsFaulted)
{
// handle exception
}
else if (task.IsCompleted)
{
DownloadOperation dl = task.Result;
// handle completion (e.g. add to your listbox)
}
else
{
// should never get here....
}
}
}
I hope this is not too late but I know exactly what you are talking about. I'm also trying to resume all downloads when the application starts.
After hours of trying, here's the solution that works.
The trick is to let the download operation resume first before attacking the progress handler.
downloadOperation.Resume();
await downloadOperation.AttachAsync().AsTask(cts.Token);
I'm modifying the commandtext of linq-to-sql to force it to use nolock, like this...
if (db.Connection.State == System.Data.ConnectionState.Closed)
db.Connection.Open();
var cmd = db.GetCommand(db.Customers.Where(p => p.ID == 1));
cmd.CommandText = cmd.CommandText.Replace("[Customers] AS [t0]", "[Customers] AS [t0] WITH (NOLOCK)");
var results = db.Translate(cmd.ExecuteReader());
It's an MVC application, so the datacontext is in the base controller, and may have been used before this code, and more importantly, after. Should I be closing the connection in this routine? Or not at all? Or only if I opened it here?
Update:
I'm now using the more general function (in the DataContext class) to modify the commandtext, and closing the connection if it was opened here. And the open has been moved down to the ExecuteReader. So far it has been working and reducing the sporadic deadlock issues. The results do not have to be right-up-to-the-second.
public List<T> GetWithNolock<T>(IQueryable<T> query)
{
// to skip nolock, just...
// return query.ToList();
List<T> results = null;
bool opened = false;
try
{
if (Connection.State == System.Data.ConnectionState.Closed)
{
Connection.Open();
opened = true;
}
using (var cmd = GetCommand(query))
{
cmd.CommandText = Regex.Replace(cmd.CommandText, #"((from|inner join) \[dbo.*as \[t\d+\])", "$1 with (nolock)", RegexOptions.IgnoreCase);
results = Translate<T>(cmd.ExecuteReader()).ToList();
}
}
finally
{
if (opened && Connection.State == System.Data.ConnectionState.Open)
{
Connection.Close();
}
}
return results;
}
I have found in the past that using a Transaction in the recommended way causes the site to run out of connections overnight. As far as I know, that's a bug in linq-to-sql. There may be ways around it, but I'm trying to keep my main code straightforward. I now "just" have to do this...
var users = GetWithNolock<User>(
Users
.Where(u => my query
);
If you Open it, you should Close it. Other LinqToSql operations match this pattern.
In my code, I unconditionally open the connection and close the connection in a finally. If someone passes me an open connection, that's their fault and I happen to close it for them.
You could delay opening the connection until just before ExecuteReader.