-
Notifications
You must be signed in to change notification settings - Fork 1
Exceptions and exception handling
To help the user to figure out what exactly went wrong and to help in taking corrective actions the Exception model tries to throw meaningful and detailed exceptions. Since there are multiple different batching modes and therefore different behavior and different ways for the operations to fail, there are multiple different Exception types. In addition to those, a few general Exception types exist.
This exception will be thrown from the constructor if some required parameter is null.
This exception is thrown from the constructor if something in the initialization phase fails.
This exception is thrown when entity validation fails in insert, replace or merge operations, batched and non-batched.
The EntityValidationErrors
property is a Dictionary<TData, List<string>>
that has each entity with validation issues as key and the list of validation issues as value. So from there you can pick the ones that caused the issues.
Example:
var entity = new MyEntity()
{
PartitionKey = "Secret Agents",
RowKey = "James Bond\t007", // contains an illegal char, \t
};
store.UseClientSideValidation = true;
try
{
await store.InsertAsync(BatchingMode.None, entity);
}
catch(AzureTableDataStoreEntityValidationException<MyEntity> e)
{
List<string> validationErrors = e.EntityValidationErrors[entity];
// validationErrors[0] is "Row key contains illegal characters"
// Do something...
}
A generic exception, when no specific exception type fits the context. These are thrown for example in situations like failing to initialize a table or a blob container, failing to translate a LINQ query expression to a table query, invalid parameters, and generally from all methods before any table or blob operations have occurred.
The InternalException usually contains the actual source of the issue.
Represents a failure of a single operation. This is thrown from insert, replace, merge and delete operations when there's only one entity to process.
The exception contains Entity
property of type TData
that holds the reference to the failing entity, and a list of blob operation exceptions, BlobOperationExceptions
with type List<AzureTableDataStoreBlobOperationException<TData>>
that holds any blob operation errors if there were any when processing this insert/merge/replace/delete. If the error wasn't a blob operation error, the InnerException usually holds the actual exception that caused the failure.
Example:
// Setting up a failure.
var explodingStream = new Mock<Stream>();
mockStream.Setup(s => s.CanRead).Returns(true);
mockStream.Setup(s => s.Seek(It.IsAny<long>(), It.IsAny<SeekOrigin>()))
.Throws(new Exception("BOOM!")); // this will get called and throws
mockStream.Setup(s => s.Length).Returns(100);
var entity = new MyEntity()
{
PartitionKey = "Secret Agents",
RowKey = "James Bond 007",
MyBlob = new LargeBlob("image.png", explodingStream.Object, "image/png")
};
try
{
await store.InsertAsync(BatchingMode.None, entity);
}
catch(AzureTableDataStoreSingleOperationException<MyEntity> e)
{
LargeBlob blob = e.BlobOperationExceptions[0].SourceBlob; // blob that caused the issue
MyEntity ent = e.BlobOperationExceptions[0].SourceEntity; // the parent entity
Exception ex = e.InnerException; // Exception "BOOM!"
}