Azure documentDB - id conflicts not throwing exception - azure-cosmosdb

I am writing a simple API that posts a json document to a single collection in DocumentDB. What is strange, is that I get no exception or indication of error when I try to add a document with the same id more than once.
public static async Task<ResourceResponse<Document>> CreateDocument(Database database, DocumentCollection collection, object obj)
{
try
{
Uri collUri = UriFactory.CreateDocumentCollectionUri(database.Id, collection.Id);
return await client.CreateDocumentAsync(collUri, obj, null, true);
}
catch (DocumentClientException e)
{
// nothing is ever caught...
}
}
The behavior I see is that the first document saves. I can see it in the document explorer. Then if I change data and keep the same id, the code appears to work, but the updated document does not actually get saved, however I dont get an exception as expected. Am I wrong to think there should be an exception here?

In the event of a conflict, DocumentDB throws a Microsoft.Azure.Documents.DocumentClientException with the message: {"Errors":["Resource with specified id or name already exists"]}.
The reason (most likely) you are not seeing the exception is that the code you have runs asynchronously. In other words, your code may be ending execution before the result of the create operation has returned. You can resolve the async method simply by calling .Result.

Related

Deserialisation error and logging the partition, topic and offset

I am handling deserialisation error using the ErrorHandlingDeserialiser sent on my DefaultKafkaConsumerFactory.
I have code a custom
try (ErrorHandlingDeserializer<MyEvent> errorHandlingDeserializer = new ErrorHandlingDeserializer<>(theRealDeserialiser)) {
errorHandlingDeserializer.setFailedDeserializationFunction(myCustomFunction::apply);
return new DefaultKafkaConsumerFactory<>(getConsumerProperties(), consumerKeyDeserializer, errorHandlingDeserializer);
}
My custom function does some processing and publishes to a poison pill topic and returns null.
When a deserialisation error occurs, I would like to log the topic, partition and offset. The only way I can think of doing this is to stop returning null in the function and return a new sub type of MyEvent. My KafkaListener could then interrogate the new sub type.
I have a #KafkaListener component, which listens for the ConsumerRecord as follows:
#KafkaListner(....)
public void onMessage(ConsumerRecord<String, MyEvent> record) {
...
...
// if record.value instance of MyNewSubType
// I have access to the topic, partition and offset here, so I could log it here
// I'd have to check that the instance of MyEvent is actually my sub type representing a failed record.
}
Is this the way to do it? I know null has special meaning Kafka.
The downside of this sub type approach is, I'd have to create a subtype every type using the ErrorHandlingDeserialiser.
Don't use a function; instead, the thrown DeserializationException is passed directly the container's ErrorHandler.
The SeekToCurrentErrorHandler considers these exceptions to be fatal and won't retry them, it passes the record to the recoverer.
There is a provided DeadLetterPublishingRecoverer which sends the record.
See https://docs.spring.io/spring-kafka/docs/current/reference/html/#annotation-error-handling
and
https://docs.spring.io/spring-kafka/docs/current/reference/html/#dead-letters

JavaFX - Handle Exceptions in one place

I am working on JavaFX application and I want to know if there is a way to handle exceptions in one place.
I am doing inserts into database. And when an insert fails, I get an SQLException.
So, is it possible to handle all SQLExceptions (for all inserts) in one place?
I'm aware of:
Thread.setDefaultUncaughtExceptionHandler(...);
But this is probably not the way to go?
It is bad practice to call any code that executes your SQL query (or any other business logic that may take long to execute) directly in the JavaFX application Thread. (I've observed that under Windows JavaFX applications crash without even printing a stacktrace when an uncaught exeption is thrown in the application thread.)
I would suggest to call your SQL-related code using an javafx.concurrent.Task.
Using the setOnFailed() method you can have code invoked whenever an Execption is thrown. There you can look for the type of exception and call any method that handles your SQLException.
Task<SOME_TYPE> mySqlTask = new Task<>() {
#Override
protected SOME_TYPE call() throws Exception {
... // do sql stuff
return mySqlResult; // or null if not needed
}
};
mySqlTask.setOnFailed(event -> {
Throwable exception = mySqlTask.getException();
if (exception instanceof SQLException) {
// call code that handles the sql exception
}
});
// start the task in a separate thread (or better use an Executor)
new Thread(mySqlTask).start();
By the way, I don't think that using Thread.setDefaultUncaughtExceptionHandler(...); is the way to go neither.

Error using Server.Execute outside of controller

I am trying to run Server.Execute outside of the controller from an external function. I have tried passing numerous types of objects trying to get this to work, but each time I get an error saying Error: Error executing child request for [url]
This is how my code looks inside of the controller:
public async Task<ActionResult> Exec(){
var http = HttpContext; //<- doesn't work
http = HttpContext.ApplicationInstance.Context; //<- doesn't work
return execMethodAsync(http);
}
Then in another class the code is:
public async Task execMethodAsync(HttpContext context){
context.Server.Execute("/myurl"); // <-- Throws error
}
I have tried passing a number of object types to this method but still get this error.
I tried passing HttpContext, HttpContext.CurrentHandler, ControllerContext.HttpContext and even some other ones, but still get this error. It seems nearly impossible to run Server.Execute() outside of the controller. Can someone please help with executing Server.Execute outside of the controller?
A few things could be causing this, have you tried
HttpContext.Current.RewritePath("yourpage.aspx");

Chain the completion of an async function to another

I am working on a Windows Store (C++) app. This is a method that reads from the database using the web service.
task<std::wstring> Ternet::GetFromDB(cancellation_token cancellationToken)
{
uriString = ref new String(L"http://myHost:1234/RestServiceImpl.svc/attempt");
auto uri = ref new Windows::Foundation::Uri(Helpers::Trim(uriString));
cancellationTokenSource = cancellation_token_source();
return httpRequest.GetAsync(uri, cancellationTokenSource.get_token()).then([this](task<std::wstring> response)->std::wstring
{
try
{
Windows::UI::Popups::MessageDialog wMsg(ref new String(response.get().c_str()), "success");
wMsg.ShowAsync();
return response.get();
}
catch (const task_canceled&)
{
Windows::UI::Popups::MessageDialog wMsg("Couldn't load content. Check internet connectivity.", "Error");
wMsg.ShowAsync();
std::wstring abc;
return abc;
}
catch (Exception^ ex)
{
Windows::UI::Popups::MessageDialog wMsg("Couldn't load content. Check internet connectivity.", "Error");
wMsg.ShowAsync();
std::wstring abc;
return abc;
}
} , task_continuation_context::use_current());
}
I'm confused how to return the received data to the calling function. Now, I am calling this function in the constructor of my data class like this:
ternet.GetFromDB(cancellationTokenSource.get_token()).then([this](task<std::wstring> response)
{
data = ref new String(response.get().c_str());
});
I am getting a COM exception whenever I try to receive the returned data from GetFromDB(). But this one runs fine:
ternet.GetFromDB(cancellationTokenSource.get_token());
Please suggest a better way of chaining the completion of GetFromDB to other code. And how to get the returned value from inside the try{} block of GetFromDB() 's then. Please keep in mind I am a very new student of async programming.
If the continuation of the call to GetFromDB is happening on the UI thread (which I believe it will by default, assuming the call site you pasted is occurring in the UI thread), then calling get() on the returned task will throw an exception. It won't let you block the UI thread waiting for a task to finish.
Two suggestions, either of which should fix that problem. The first should work regardless, while the second is only a good option if you're not trying to get the response string to the UI thread (to be displayed, for example).
1) Write your continuations (lambdas that you pass to then) so that they take the actual result of the previous task, rather than the previous task itself. In other words, instead of writing this:
ternet.GetFromDB(...).then([this](task<std::wstring> response) { ... });
write this:
ternet.GetFromDB(...).then([this](std::wstring response) { ... });
The difference with the latter is that the continuation machinery will call get() for you (on a background thread) and then give the result to your continuation function, which is a lot easier all around. You only need to have your continuation take the actual task as an argument if you want to catch exceptions that might have been thrown by the task as it executed.
2) Tell it to run your continuation on a background/arbitrary thread:
ternet.GetFromDB(...).then([this](task<std::wstring> response) { ... }, task_continuation_context::use_arbitrary());
It won't care if you block a background thread, it only cares if you call get() on the UI thread.

Calling FluentMigrator methods inside Execute.WithConnection action

Calling FluentMigrator's builder methods while inside the action that I pass to Execute.WithConnection causes a null reference exception to be thrown.
What I am trying to do is select some data so that I may manipulate it in c#, as that is easier than manipulating it in T-SQL, and use the result of my c# operations to update the data or insert new data (to be more specific, I need to pick one query string parameter out of a stored url string and insert it somewhere else).
The only way I see to select data within a migration is to use Execute.WithConnection and retrieve the data myself (FluentMigrator provides no helpers for selecting data), but if I try to use any fluent migrator expression in the action I pass to Execute.WithConnection a null reference exception is thrown.
Here is a boiled down version of my code:
[Migration(1)]
public class MyMigration : Migration
{
public void Up()
{
Execute.WithConnection(CustomDml);
}
public void CustomDml(IDbConnection conn, IDbTransaction tran)
{
var db = new NPoco.Database(conn).SetTransaction(tran); // NPoco is a micro-ORM, a fork of PetaPoco
var records = db.Fetch<Record>("-- some sql"); // this is immediately evaluated, no reader is left open
foreach (var r in records) {
var newValue = Manipulate(r.OriginalValue);
Insert.IntoTable("NewRecords").Row(new { OriginalValueId = r.Id, NewValue = newValue }); // <-- this line causes the exception
}
}
public void Down() {}
}
The line that calls Inser.IntoTable causes a null exception to be thrown from line 36 of FluentMigrator\Builders\Insert\InsertExpressionRoot.cs - it appears that the _context variable may be null at this point but I do not understand why this is. (when testing Create.Table, e.g., it occurs on line 49 of FluentMigrator\Builders\Create\CreateExpressionRoot.cs)
Any help would be appreciated. Perhaps there is disagreement on whether DML is appropriate in a migration, and I am open to suggestions, but this scenario has come up twice this week alone. For now I am simply performing the insert using my micro-ORM within the action rather than FluentMigrator and that does work, but it seems like what I am trying to do should work.
When using the Execute.WithConnection expression all you get is the db connection and the transaction.
Using Execute.WithConnection creates an PerformDBOperationExpression expression. When processing the expression, a processor calls the Operation property (an example in the SqlServerProcessor) and the processor does not have a reference to the MigrationContext. But even if it did have access to the MigrationContext, when FluentMigrator has come to the processing stage, it is already too late. You would be trying to process expressions in a expression and at the moment FluentMigrator is not built to handle that type of nesting.
An alternative would be to make the connection string available in the migration context, see this issue: https://github.com/schambers/fluentmigrator/issues/240
Would that be a better approach?

Resources