We have several large and small Access databases that support users across the state. Recently, I've been trying to add error checking into these datasbases since many where orginally created without it. However, some of these databases have a lot of functions and adding error checking to each one seems overly tedious.
I basically just want the database to send me an email with a description of the error and object/function on which it occurred. Is there an easier way to do this than to add error checking to each function?
While not exactly an answer (or, should I say, not the answer you want), my response to this question holds true in this case as well. In either case, I don't think you can just throw some generic function into your code, or do so without editing every pre-existing function. If proper error trapping is built into your application, you never have to worry about it.
Related
For some reason I only recently found out about unique constraints for Core Data. It looks way cleaner than the alternative (doing a fetch first, then inserting the missing entities in the designated context) so I decided to refactor all my existing persistence code.
If I got it right, the gist of it is to always insert a new entity, and, as longs as I have a proper merge policy, saving the context will take care of the uniqueness and in a more efficient way. The problem is every time I save a context with the inserted entity I get a NSCoreDataConstraintViolationException, no error though. When I do the fetch to make sure
there is indeed only one instance with a unique field
other changes to this entity were applied
everything seems to be okay, but I’m still concerned about this exception, since I do saves and therefore get it quite often, a few times per second in some cases.
My project is in objective-c and I know exceptions are expensive there so I’m having doubts if I’m missing something.
Here is a sample project with this issue (just a few lines of code, be sure to add an exception breakpoint)
NSMergeByPropertyObjectTrumpMergePolicy and constraints are not useful tools and should also never be used. The correct way to manage uniqueness is with a fetch before the insert as it appears you have already been doing.
Let's starts with why the only correct merge policy is NSErrorMergePolicy. You should only be writing to core data in on synchronous say (performBackgroundTask is not enough you also need an operation queue). If you have two performBackgroundTask running at the same time and they contradict then you will lose data. Merge policy is answer the question of "which data would you like to lose?" the correct answer is "Don't lose my data!" which is NSErrorMergePolicy.
The same issue happens when you have a constraint. Let's says you have an entity with a unique constraint on the phone number. And you try to insert another entity with the same phone number. What would you like to happen? It depends on what exactly the data is. It might be two different people, and the phone number should be made different (perhaps they were lacking area code), or it might be one person and the data should be merged. Or you might have a constraint on an uniqueID and the number should just be incremented. But on the database level it doesn't know. It always just does a merge. It will silently lose data.
You can create a custom NSMergePolicy and inspect NSConstraintConflict to decide what do to. But in practice you'd have to think about every time you edit the database and what each change means, which can be very hard outside of the context of writing a change to the database. In other words, the problem with a constraints and merge policy is that it the run is on the wrong level of your application to effectively deal with the problem.
Using constraints with a merge policy of error is OK, as it is a way to find problems with your app (as long as you are monitoring crashes and fixing them). But you still need to do the fetch before the insert to make sure the error doesn't happen.
If you want to clean up code then just have one place that you create your objects. Something like objectWithId:createIfNeed:inContext: which does the fetch and create.
I do not know how to implement a proprietary handling procedure of user defined errors (routines/algorithm stop) or warnings messages (routine/algorithm can proceed) without using Exceptions (i.e. failwith .... Standard System Exception).
Example: I have a Module with a series of Functions that uses a lot of input data to be checked and to be used to calculate the thickness of a Pressure Vessel Component.
The calculation procedure is complex, iterative and there are a lot of checks to be performed before getting a result, check that can generate "User Defined Errors" that stop the procedure/routine/algorithm or generate a "Warning Messages" proceeding on.
I need to collect these Errors and Messages to be shown to the User in a dedicated form (Wpf or Windows form). This later at the end.
Note: every time that I read a books of F# or C# or Visual basic or an Article in Internet, I found the same Phylosophy/Warning: raise of System/User-Defined Exception should be limited as much as possible: Exception are for unmanageable Exceptional Events ( not predictable) and cause "overload" to the Computer System.
I do not know which handling philosophy to implement. I'm confused. Limited sources available on internet on this particular argument.
Actually I'm planning to adopt this Phylosophy , taken from: "https://fsharpforfunandprofit.com/posts/recipe-part2/". It sounds good for me, ... complex, but good. No other references I was able to go find on this relevant argument.
Question: there are other Phylosophies that I can consider to create this Proprietary handling/collecting of user defined errors? Some books to read or some articles?
My decision will give a big impact on how to design and write my code (splitting problem in several functions, generate a "motor" that run in sequence functions or compose then in different ways depending on results, where to check for Errors/Warnings, how to store Errors and Warning Messages to understand what is going on or where "Errors/Warnings" are genetate and caused "By Which Function"?).
Many thanks in advance.
The F# way is to encode the errors in the types as much as possible. The easiest example is an option type where you would return None if the operation failed ans Some value when it succeeded. Surprisingly, very often this is enough! If not, then you can encode different types of errors AND a success "state" in a discriminated union, e.g.
[<Measure>]
type psi
type VesselPressureResult =
| PressureOk
| WarningApproachingLimit
| ErrorOverLimitBy of int<psi>
and then you will use pattern matching to "decide" what to do in each case. If you need to add more variants, e.g. ErrorTooLow, then you would add that to the DU and then the compiler will "tell" you about all places where you need to fix the logic.
Here is the perfect source with detailed information: https://fsharpforfunandprofit.com/series/designing-with-types.html
I’ve seen Objective C code using a collection of practices, raging from passing a pointer of NSError for execution finish status - to using NSAssert - to implementing #throw - to relaying on delegate for status code returned in the callback - to the old c method of returning a boolean/int indicating with 1 being success and co.
I can’t identify a consistent pattern for how should I be handling errors happening in my app running on client devices. For ex, what would you recommend handling for the following cases:
Client attempt to access a network resource, network resource timed out / returned 500?
Unexpected state that should have not even happened reached in logical code section?
Attempt to write to disk failed? (Out of disk space, not permission and code)
Coming from Java, server side practices exceptions the weapon of choice, using Objective C and C is seems that exceptions exist but are not encouraged. NSAssert seems harsh, as it will crash the application, which in most cases is not the optimal solution. So, I’d appreciate a Best practices advice.
Exceptions are used to indicate programmer error and/or non-recoverable errors only. Exceptions should not be used for flow control. NSAssert is more of a development tool. Use NSError for recoverable, user addressable (or caused) errors.
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/ErrorHandling/ErrorHandling.html
First we have to agree upon the terminology. I think there are two types of bad situations in a program: Errors and Exceptions.
Errors An unwanted situation that can happen but you can recover from it with the program memory being in a consistent state and further execution can continue.
eg1. Client attempt to access a network resource, network resource timed out / returned 500?
eg2. Attempt to write to disk failed? (Out of disk space, not permission and code)
Approach Handle the error the way you want it handled. Show user message, log it to file/console, report it to your back-end if you think it needs to be reported.
Exceptions A state that should never have been reached and may corrupt the memory state of the app in a way that prevents further execution.
This could happen at two levels.
Level 1 A logic error that you have overlooked and is now causing the exception.
eg1. accessing invalid array elements i.e. index out of bound exception.
In the above example, you unconsciously made a programming mistake. You couldn't have handled it because you overlooked it. This will crash the application.
Approach Your approach here should be to identify the bug and fix it. In the process some end users will be affected which is the case with the most meticulous software.
Level 2
As you are programming, you come across a situation that your business logic doesn’t permit.
eg1. Unexpected state that should have not even happened reached in logical code section?
eg2. A database entry that you always expect to be present as per your business logic. For example, let's say you are making an app that requires a currency table with currency names, unicode symbols for currencies and country names. The value from this table are to be shown as a drop down in your UI. You may create a table upon first launch of the app and insert the values or may be you ship the table in the bundle but you always expect it to have the values you are inserting. You make an sqlite select query->sqlite execution succeeds->but no values are returned. Business logic demands that values should be present but for some mysterious reason they are absent.
Here is where most confusion stems from because sometimes you can recover from some of these situations by treating them as errors and displaying a message to the end user. This approach is wrong. This is an exception at business logic level. One that you should prevent from happening.
Approach You should force crash the app here as well using NSAsserts both in development and production mode. This is an aggressive approach and some end users will be affected, but I have read experts advising to adopt an aggressive approach to finding bugs and remedying them rather than pretending they don’t exist or thinking you have smartly covered them all when all you have done is masking exceptions as errors through your “handling tactics”. I believe the experts are right. Coming from Java, you may find it a very objCeee.. way of doing things.
Nils and Bools You should understand that they are just facilitators to reach at the conclusion of whether you treat something as an error or exception. They are not the end in themselves. While writing your methods with return value, you should define what a nil or bool(no) signifies and document your intent on top of the method. Sometimes it would be an error, sometimes it would be an exception, sometimes it could be a normal expected result. While dealing with apple frameworks/third party libraries you should understand what their intent is when they return such values and determine how you want to treat them in your code.
Some other tips
Don’t use #try/catch because experts say so. If you wish to challenge them assuming that Apple has put it there for a reason, Apple is always right, experts(including Apple employees themselves) have got it wrong after all these years, you can go ahead and do it.
Formalize your approach to this->stick to it->document your intent. Don’t think it over and over. Because at some stage error/exceptions/nils/bools would cross the limits of propriety and reach the precincts of taste. You will be better off settling this once and for all and freeing up your time.
Let me explain this question a bit :)
I'm writing a bunch of stored procedures for a new product.
They will only ever be called by the c# application, written by the developers who are following the same tech spec I've been given.
I cant go into the real tech spec, so I'll give an close enough example:
In the tech spec, we're having to store file data in a couple of proprietary zip files, with a database storing the names and locations of each file within a zip (eg, one database for each zip file)
Now, lets say that this tech spec states that, to perform "Operation A", the following steps must be done:
1: Calculate the space requirements of the file to be added
2: Get a list of zip files and their database connection strings (call stored proc "GetZips")
2: Find a suitable location within the zip file to store the file (call stored proc "GetSuitableFileLocation" against each database connection, until a suitable one is found)
3: In step 2, you will be provided with a start/end point within the zip to add your file.
Call the "AllocateLocationToFile" stored proc, passing in these values, then add your file to the zip.
OK - so the question is, should "AllocateLocationToFile" re-check the specified start/end points are still "free", and if not, raise an exception?
There was a bit of a discussion about this in the office, and whilst I believe it should check and raise, others believe that it should not, as there is no need due to the developer calling "GetSuitableFileLocation" immediately beforehand.
Can I ask for some valued oppinions?
Generally, it is better to be as safe as possible. A calling code should never rely on an external code (the sps are kind of external). The idea is that you can not predict what would happen in the future. New guys come to the company... the sps are given to another team and so on...
Personally, the fact that B() is right after A() doesn't guarantee anything. To change this for whatever reason is not something to be considered impossible.
A team should never take decisions based on "we are going to maintain this, no problem at all" because they might get fired, the company may sell the product and so on..
My suggestion is to do the checking, profile the code and if it is really a bottleneck to remove it, but write somewhere that THIS CAN BREAK!.
Given that you're manipulating files, with all the potential havoc this can create, I'd say in this scenario the risk (damage component) is high enough to be cautious.
And Svetlozar's right: what if great success does cause re-use, or other added-on applications? Not everyone may be as well-behaved as your team is right now.
One reason why it might be a good idea would involve race conditions. Is it possible two users could call the process at the same time and get the same values? Please at least test this scenario with the currently designed process.
Is there a way to programmatically check for database object corruption in Access 2003?
My development project has gotten complex enough that it's hard to manually check all the objects after a day of programming to see if some small control, form, report, query, or code object has been corrupted somehow. I already have the data split off into a separate SQL Database stored on another machine, and this project is merely a front-end application to work with the data.
Mostly an academic musing, as I just don't want to get so far - then have corruption put me back several weeks because some seldom used object got corrupted way back when.
Any ideas out there? Thanks in advance for any pointers!
EDITED 12/03/2009 # 11:51
Sadly, I can only accept one answer - though I got a few very good ones, thank you for all the pointers!
You might like to look at: Is it possible to programmatically detect corrupt Access 2007 database tables?
I am inclined to keep a copy of important databases at each compact & repair and to compare the new database against the previous one. You can also check for non-standard characters.
Neither Compact/Repair nor Decompile/Recompile catches all corruption problems, although you should be doing this anyway.
I use a function to export all Container Docs (and QueryDefs) using SaveAsText into a date/time stamped folder, and use it regularly throughout the day. If I suspect any corruption, I create a new mdb, and use LoadFromText to recreate the objects.
Proper compilation practices will prevent corruption of the VBA project (which is what you're talking about here).
That entails:
use OPTION EXPLICIT in all modules.
turn off COMPILE ON DEMAND in the VBE options.
compile your code regularly, while working.
periodically (e.g., once a day after a full day of coding) decompile and recompile the code.
If you do this, you'll never encounter corruption in the first place so you won't need to test for it (which is impossible in the first place).