I am writing some data access code and I want to check for potentially "invalid" data states in the database. For instance, I am returning a widget out of the database and I only expect one. If I get two, I want to throw an exception. Even though referential integrity should prevent this from occurring, I do not want to depend on the DBAs never changing the schema (to clarify this, if the primary key constraint is removed and I get a dupe, I want to break quickly and clearly).
I would like to use the System.IO.InvalidDataException, except that I am not dealing with a file stream so it would be misleading. I ended up going with a generic applicationexception. Anyone have a better idea?
InvalidDataException seems pretty reasonable to me:
The name fits perfectly
The description fits pretty reasonably when you consider that it's effectively a data "stream" from the database
Nothing in the description mentions files, so I wouldn't be worried about that side of things
You're effectively deserializing data from a store. It happens to be an RDBMS, but that's relatively unimportant. The data is invalid, so InvalidDataException fits well.
To put it another way - if you were loading the data from a file, would you use InvalidDataException? Assuming you would, why should it matter where the data is coming from, in terms of the exception being thrown?
If you need an exception that would exactly describe the situation you're dealing with, why not make your own exception?
Just inherit it from System.Exception.
I might be tempted to use one of the following:
InvalidConstraintException
NotSupportedException
OverflowException
Or, just go ahead and create my own: TooManyRowsException
You could write a custom exception if you do not find any suitable standard-exception ...
But, you say:
Even though referential integrity
should prevent this from occurring, I
do not want to depend on the DBAs
never changing the schema.
When someone changes the DB schema, changes are pretty big that you'll have to make some modifications to your application / data-access code as well ...
Related
I have been using Entity Framework 6 and trying to handle some common problems like Primary/Foreign/Unique Key constraints via EF. EF gives SqlException as an InnerException and it seems that - as far as I found upto now - the only way to understand the actual problem is using error codes in that SqlException object?
I would like to abstract these exceptions by catching EF exceptions and throwing my own exceptions by analyzing the error code in the InnerException. I have some considerations at that point.
SQL Server codes change by the server version or not? Should I handle
different versions of SQL Server in a different way like creating different implementations for 2008, 2012 and etc?
Instead of SQL Server it is possible to use other SQL Servers like
MySQL and its another reason I am trying to abstract these
exceptions.
For example, as in the accepted answer of that question, I would like catch specific errors, but instead of rethrowing I would like to throw my own exception(s). If I do not want to do something special or I do not have any special exception for the error I can create and use a more generic exception in which I can store the original exception into that generic exceptions InnerException field.
I read this blog post and unfortunately the problematic case was my first way to go. I would like to do that without using any third party library as much as possible (of course this is not more important doing it right). I wonder if there is tested and accepted way of doing this, otherwise I am open to any suggestion.
SQL Server codes change by the server version or not?
Exception numbers cannot change once released. Deadlock is and will remain 1205, unique index duplicate key is and will remain 2601, unique constraint violation is and will remain 2627 and so on and so forth. But, you see, in the very examples I choose I show you the danger lurking in relying on these: what decides the difference between 2601 and 2627? Your friendly DBA can decide that it should drop an unique index and instead add an unique constraint (enforce by an index, but that is irrelevant) and all of the sudden your app sees new errors. By doing deep inspection of the exception you add coupling between the application code and the SQL storage, and risk breaking the app when the storage modifies in what would otherwise be a completely transparent change (eg. add an index). Be warned.
I think is feasible to add handling for several well known cases. But you must allow for generic exception you are not aware of ad development time, and handle those.
As for cross-platform, you would have to customize for each platform. The good news is that a 'primary key violation' is the same concept on SQL Server and on MySQL, so you could translate it to a PrimaryKeyViolationException for both providers. Is not trivial, but it is possible.
And finally, a heads up: I've seen folk trying to do similar before, to mix results. The benefits are not exactly overwhelming, and the effort put in is considerable.
I have an application that takes a ZIP code from the user which may or may not be valid for the selected state. I consider the case of an invalid ZIP code to be a rare issue that would really only result from a typo.
The relevant SQL tables are Quote and Address. Saving a quote is done in one database call, with all parameters for both tables being supplied to a stored procedure.
Currently in the case of an invalid ZIP code an exception is raised in the stored procedure, caught in C# at the data layer, and a custom InvalidZipCodeException is thrown. The custom exception is then caught at the UI layer and the user is notified of the error. I originally designed it this way to avoid an extra database call to check the validity of the ZIP code every time a quote is saved.
I've recently read some materials on data validation and realized I'm using exceptions to control logic flow here, which is generally frowned upon. It seems silly to me to make a separate database call just to validate the ZIP code when the overwhelming majority of cases involve valid data. I'd like some more educated opinions on whether my design is poor in this specific case.
As JohnLBevan suggests in the comments, it's really not worth reworking it if (1) it's already working OK and (2) it's consistent with how the rest of the application validates. While it is currently thought to be bad practice to control logic flow with exceptions, like anything else it's a judgement call.
You mentioned that every 5 digit number is not a valid zip code... I imagine you have a table that stores a map to validate. Just store that as a dictionary and validate against it client-side, if you end up changing the validation. For me, I would say, "If it ain't broke, don't fix it" in this case.
I am going to handle a project to a client for a testing phase, the project build with ASP.NET MVC3 .. What I need is to save all exceptions occurs to a persistent location -SQL Database-
and I have some questions..
what field should I save in the database? (Msg, trace, etc)
I have seen people save the inner exception but sometimes my exceptions have null inner exception.
What is the best place to handle the error and save to the DB. (In global.asax OR defining a custom error page in web.config and get the last error with server.getLastError)
what field should I save in the database? (Msg, trace, etc)
Everything you can, if possible:
Type
Message
Stack trace
I have seen people save the inner exception but sometimes my exceptions have null inner exception.
And some will have more than one, nested. You should save everything you can, IMO. How you structure that is up to you, but you could always add the innermost one, then the containining one with a foreign key to the innermost one, etc, working your way outwards.
What is the best place to handle the error and save to the DB.
Can't help you on that part, I'm afraid. You may want to consider doing this asynchronously though, queuing them up. This is particularly relevant when the exception may itself be a database error - if you can build up a queue (with a maximum size, of course) so that once any database problems have been restored, the errors can then be stored, that could be useful. Or potentially dump them to disk first, and periodically upload that log to the database.
As Jon Skeet said, the more fields you save the more data you will have to diagnose the problems as you go. Personally, I'd go for serializing the exception and putting it in the "XML" type column if you have the ability to do so (database space and performance considerations). This would also eliminate the second problems since the inner exception will be serialized also. Though with this approach all your custom exceptions should be able to serialize themselves correctly.
I'd recommend looking at freely available source codes for error loggers such as Elmah to get the basic idea.
Some of the answers and comments to this question: Simplest C# code to poll a property?, imply that retrieving data from a database in a property's getter is Generally a Bad Idea.
Why is it so bad?
(If you have sources for your information, please mention them.)
I will usually be storing the information in a variable after the first "get" for reuse, if that influences your answer.
Because retrieving data from a database could cause any number of exceptions, and property getters, as a rule, should never throw exceptions.
The expected behavior of a property getter is just to return a value; if it's actually doing a lot more than that, it should be a method.
Microsoft's guide for Property Design explains the reasons:
https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/property
It's bad because (among other things) it violates the Principle of Least Astonishment.
Programmers generally expect properties to do simple gets/sets. Encapsulating data access in a property, which could throw exceptions, cause side effects, and change the state of the data in the database, is not what is generally expected.
I'm not saying there is no case for complex properties - sometimes, it can be a good solution. But, it is not the expected way to do things.
The Short Version: Making a property getter directly access a database would violate The Separation of Concerns principle.
More Detail:
Generally speaking, a property is intended to represent data associated with an object, such as the FirstName property of a Person object. Property values may be set internally or externally, but the act of modifying and retrieving this data on the object should be separated from the act of retrieving or committing that data to a permanent store.
Any time you accessed the getter, you'd be making another call out to your database.
A getter, by definition, should just be encapsulating data, not functionality.
Also, you would likely be redefining functionality and making many trips to the database if you had more than one getter that needed to round-trip to the database. Why not handle that in a centralized place rather than splitting that out among multiple properties?
Methods are for class-level data modification and functionality, properties are for individual data modification and retrieval only.
Besides exceptions being likely, querying a database is a slooooow operation. In both aspects, using property getters as a database accessor violates the principle of least astonishment to client code. If I see a library class with a property, I don't expect it to do a lot of work, but to access a value that's easily retrieved.
The least astonishing option here is to provide an old fashioned, simple Get function.
If you are indeed only retrieving the value from the database and not also writing its value back, such as a read only property, there is nothing inherently wrong. Especially if the property cannot exists without its parent. However in implementation it can cause maintainability problems. You are coupling the process of retrieving stored information with access to that information. If you continue to follow this pattern for other properties, and aspects of your storage system change, the change could proliferate throughout your code base. For example a table name or column data type change. This is why it is bad to have database calls in your property getter.
On a side note: if the database is throwing exceptions when you try to retrieve the value, then obviously there is a bug in your code (or the calling client's code) and the exception will still surface regardless of where you put the data access code. Many times data is backed by some sort of collection within the class that can throw exceptions and it is standard practice to store property values in this manner (see EventHandlerList).
Properties were designed specifically because programmers need to perform additional logic when getting and setting values, such as validation.
With all of that having been said, reexamine your code and ask yourself "how easy will this be to change later?" from there you should be on your way to a more maintainable solution.
Is it best practice to check whether a value is null coming from a database even though there are constraints on the column which disallow nulls.
Thanks in advance
What you're talking about is defensive programming. I like to think it's good to practice it when you don't trust your input. You might think you can trust your DB now, but what if in the future you decide that column should have a NULL value somewhere? Then you need to change your code everywhere you assumed it wasn't?
If you don't ever think you'll change it (like it's a primary key or something) then I don't think you need to. It's more future proofing in case you one day decide to change your schema. If that column will never have a case where NULL makes sense, then you probably don't need to check. In the event you get a NULL, like commenters have said, you have a bigger problem in that your DB is probably hosed.
I'd say go ahead and add checking for Nulls on your business logic. It would be particularly useful too during unit testing. Maybe not now but in the future.
It depends on a lot of factors.
In many of my projects I strive to enable unit-testing, which would decouple the code that processed data from the code that retrieved the data (ie. by talking to the database.)
That way I could also potentially reuse the code that processed the data by feeding it data from other sources. I would absolutely safeguard input values to the logic layer in this case.
Also, applications evolve over time, so even if it is impossible for you to get null values right now, at some point it might be implemented, and a lot of old code would then suddenly get things it wasn't written to handle. I would personally want them to fail fast rather than in some cases silently process wrongly.