For Asp.net web applications, is it best to:
trap errors within sql stored procedures and test for a return value in the code or
just let the error occur in sql (dont handle it) and rely on ado.net raising the errors within the code.
What are the best practises here?
A general rule that applies here is to catch the error as near the source as possible. SQL Server now has "try ... catch ..." error trapping syntax. So use it. The overhead of the little bit of extra code is insignificant, and if you have multiple statements in your SP, you can adapt the string in RAISERROR to help localize the problem.
In the interface, it shouldn't be difficult to trap the SP error event and handle it the same way you handle other error trapping in your procedural code.
This is one of the more neglected "best practices" in stored procedures, and it's even more important than in "regular" code because it's trickier to use a step=through debugger.
One useful pattern is to handle this in your SP the same way you it expect it to be handled in any other opaque SDK library.
According this article, this is a type of "boneheaded" exception - i.e. if an error occurs in the SP, this means that there's something wrong with the SP or the data itself.
My advise would be to trap the error in aps.net, as there you have much more possibilities to log the error, as well as all the parameters passed to the SP in order to investigate the problem.
I use try/catch on all potentially error generating calls to libraries or other servers including database queries. I'm primarily a developer not a DBA so I handle the error in the language that I'm most proficient in, C# not SQL. I'm sure that'll vary for every programmer. Not handling the error is never fine in my book.
I prefer both -
the stored procedure calls RAISEERROR, which manifests as an exception in ADO.NET
the stored procedure returns an error code, in case one sproc is calling another
in general, I always make db calls inside a try-catch
The most likely failure mode in the data layer is bad user input vales such as requesting a record that doesn't exist. Most other errors are caused by defective code and usually are caught right away when testing. I like to catch the db error and and always throw a custom error with more information about the data and context of the request. Then the error bubbles back up the call stack and if it was a user correctable error I can alert them to that fact. Otherwise the central error page handler for the application will be called when the error reaches the top of the stack. The worst thing to do is to catch an error and not let it bubble back up. Return codes are outdated constructs unless talking to com components or foreign systems.
Ideally, your web application isn't aware of the back-end or data access. So it shouldn't be handling sql-related errors - those should be handled by the data access layer. But the web application needs to handle failure gracefully, by providing the end-user with a friendly message.
I would say it depends on what you are doing in your stored proc and what you want to do with certain errors that occur. Sometimes I handle it in the sp but other times i let it raise up to the data layer code.
Bear in mind, sometimes you can miss errors when using sql server 2005 try/catch, see my post on this. Whereas, in code (C# in my case) you can access all the errors in the SqlErrorCollection object.
Just be absolutely certain that your error handling in the stored procedure is well thought out and any uncertainties are left to be passed up to the data layer code where you must log everything.
The answer is that you need to do both. Some errors are actually triggered downline from the Database engine. Their source varies, of course, according to the actual way you connect to the database (OLBC, OLEDB etc). You've got to find a way of dealing with these. Some errors such as Deadlock errors out to be handled at the application level too.
As well as errors, it is a good idea to receive and deal with messages from the SQL Server Database Engine. These are very similar to errors and can give the application a lot of useful diagnostic information. If you’re using System.Data.SQLClient, you’ll need to create a SqlInfoMessageEventHandler delegate, identifying the method that handles the event, to listen for the InfoMessage event on the SqlConnection class. You’ll find that message-context information such as severity and state are passed as arguments to the callback, because from the system perspective, these messages are just like errors.
I hope this helps!
Related
How would you go about and handle lost data from a sql connection loss on a ASP.NET application.
Lets say your running an algorithm adding and removing certain roles. A midst it, the connection to the SQL database is lost. And because the connection is not there, wont even be able to backtrack the steps done. The whole state is lost, leaving the database in an error nous condition.
Would you set the IIS Rapid Fail Protection to shut the site down upon 1 exception and manually force the function to run again (after connection have been fixed).
Or how is the professional way of handling it, i am quite new to it. Maybe there's something i do not know of it (such as iis maybe trying to rerun it/caching)
(Using entity framework)
This is not a coding problem in its own way, it is more of a question of best practice handling data loss with sql database on asp.net
You need to do batch SQL Operations inside a SQL Transaction. So that whatever the error, a rollback happens. This is a built-in SQL feature and nothing special needs to be done.
Once you start a SQL Transaction, a Commit is issued only when all operations succeed. The default behavior is normally Rollback in case of all other non-success scenarios.
If you're encountering issues with any specific logic, post the code snippet and we're glad to help.
I have a custom workflow in CRM 2011 which is manually triggered against custom entity records. When a single record is selected for processing, the workflow is always successful. However when selecting more than one record, at least one will fail. The error(s) provided seem to vary from one attempt to the next, even though the same data is being used.
Errors I've encountered so far are:
ValidateOpen - Encountered disposed CrmDbConnection when it should
not be disposed You cannot create a SqlExecutionContext from another
SqlExecutionContext on which OnBeginRequest has not been called
And after restarting the DB server:
Invalid Pointer
All of these occur when calling the Update method of the IOrganizationService. The Invalid Pointer error seems to be the more common error since having restarted the DB server (it was suggested to me that it might be an issue with an overly-busy DB server). I've also deleted any backlog of asynchronous tasks in case this was the issue, but it hasn't had any effect.
Does anyone know what this error means, why I might be getting it or how I can get around the issue?
Many thanks!
It seems this error message is a round-about way of saying, 'tried to open another connection to CRM when the previous one was open', and the reason it tries to do this is very much relevant to the fact it only fails when processing more than one record.
Reference this blog:
It seems that when a workflow is run against multiple records, it uses the same instance of the class, which means that class-level variables won't be re-instantiated between executions. So, when subsequent executions come to the code which sets the class-level service variable to an instance of an IOrganisationService, it finds the variables already has one and that it's open.
The solution I've found easiest to implement it to have the service variable within the Execute function, rather than class-level. This has solved the problem everywhere that I've tried it since.
According to the CRM 2011 Web Service Error Codes...
InvalidPointer - The object is disposed.
I am trying to maximize the benefits from an experience.
Also I usually use Enterprise library logging block, I log errors and a portion of statistical information into the database, because it is centralized place to track errors, if database logging failed, Normally it goes to Event Log.
Tracing messages should go into file:
Which choice you believe we should go
1- Only Some tracing messages can be left in code if there is a complex algorithm or unstable module.
OR
2- We should not keep any tracing messages in code, clean it up as soon as bug is resolved.
For database.
I think that Errors raised from SP and functions should be logged into another table in the database, and that exactly what is done by AdventureWorksLT2008 database.
Is it a bad idea to log database events directly to Enterprise library Log table without raising this errors to next tier. I think it is more fixable, because I can put more custom information in the message. of course some errors will not be handled and will reach the next tier.
Any ideas, or comments, something else you do. something you want to clarify.
Thanks
Are you talking about catching errors and logging directly in T-SQL and not then doing RAISERROR to get it to the caller?
I think that's a viable strategy for certain kinds of issues - for instance, if an SP wants to find a problem and correct it silently and simply issue a warning.
But the kind of issues it would apply to might not be terribly frequent.
The kind of things I would think about are things like unusual cases where unexpected UPDATEs are done instead of INSERTs? Or where data already exists so is not generated. Or in a deployment or build script which skips an existing table, etc.
What if your database has performance issues and SP/functions start timing out - logging the error to the database may not work?
I inherited an application with a lot of stored procedures, and many of them have exception handling code that inserts a row in an error table and sends a DBMail. We have ELMAH on the ASP.NET side, so I'm wondering if exception management in the stored procs is necessary. But before I rip it out, I want to ensure that I'm not making a grave mistake because of ignorance about a best practice.
Only one application uses the stored procedures.
When would one prefer using exception management in a SQL Server 2005 stored procedure over handling the exception on the ASP.NET side?
If there are other applications utilizing these stored procedures then it might make sense to retain the error handling in the stored procedures. In your edit you indicate that this is not the case so removing the exception handling is probably not a bad idea.
In the MSDN article Exception Handling it is outlined when to catch exceptions and when to let them bubble up the stack. It can be argued that it makes sense to handle and log database exceptions that are recoverable from in the stored procedure.
There is a principle sometimes referred to as "First Failure Data Capture" - ie. it's the responsibility of the first "chunk of code" that indentifies an error to immediately capture it for future diagnosis. In multi-tier architectures this leads to some interesting questions about who "first" actually is.
I believe that it's quite reasonable for the stored procedure to log something to a db (sending an email sounds somewhet overkill for all but the most critical of errors but that's another issue). It cannot assume taht higher layers will be well behaved, you may only have one client now, but you can't predict the future.
The stored procedure can still throw an exception as well as logging. And sometimes in difficult situations being able to correlate errors in the different layers is actually very handy.
I would take a lot of persuading to remove that error logging.
I believe that logging to a table only works for simpler systems where everything is done within a single stored procedure call.
Once the system is complex enough that you implement transactions across database calls, logging to the database within the stored procedure becomes much more of a problem.
The rollbacks undo the logging to the table.
Logic that allows rollbacks and logging, in my opinion, creates too much potential for defects.
I have a Flex 3 app which I want to instrument to report errors generated by the app to a server via simple HTTPService call.
My idea is to wrap all the methods in try ... catch blocks which then pass the Error object to the reportError() function (which then fires off the HTTP request and pops up a dialog) but is there a better way?
I have implemented a system such as the one you suggest, wrapping all of my methods in try/catch and sending the stack trace to a service that emails me the errors. I created a basic format for the error that logs which method the error occurred in. I noticed that sometimes I end up getting null from the stack traces, so I wanted to log that information for these situations.
It GREATLY improved my application. I tracked down a (large) handful of errors and released a much cleaner build to my users. Now I don't ever get the emails.
The better way IMO is something like this.
I've no idea how good is this particular project (aside from this spooky GPL license), but I don't see why logging in action script should be any different from J2EE, C++, or say Python. Yes, it has some sand box security issues, but I think if this solved, you could log into some centralized log server..
Unfortunately, there really isn't -- errors don't bubble up in such a way as to be trappable at a global level, so the only real way you have to catch errors is to try and catch them all manually. (The community's been pretty vocal in asking for a global exception-handling feature for a while, but it's not there yet.)