What is the best practice for Wakanda to 4D error handling? - wakanda

In 4D Mobile architecture, what is the best practice for ensuring that Wakanda interactions with 4D do not error resulting in thread failure.
There can be many such interactions: query, entity reference col[0], .save, method calls, etc...
We want to trap all these errors and return our own message, rather than have the thread fail due to a Wakanda<->4D interaction failure.
Invoking an on-err-call function for all of these types of interactions would eliminate wrapping all calls in a try/catch statement.

From my knowledge, there is no such error handling strategy between 4D and Wakanda. We also experience request drops and have to code our own protective measures. I hope I am wrong and another answer makes mine irrelevant.

I had no luck asking about this on the premium forums back when they still existed. I wish I had a better answer.

Related

Fail vs. raise in Ruby : Should we really believe the style guide?

Ruby offers two possibilities to cause an exception programmatically: raise and fail, both being Kernel methods. According to the documents, they are absolutely equivalent.
Out of a habit, I used only raise so far. Now I found several recommendations (for example here), to use raise for exceptions to be caught, and fail for serious errors which are not meant to be handled.
But does it really make sense? When you are writing a class or module, and cause a problem deep inside, which you signal by fail, your programming colleagues who are reviewing the code, might happily understand your intentions, but the person who is using my code will most likely not look at my code and has no way of knowing, whether the exception was caused by a raise or by fail. Hence, my careful usage of raise or fail can't have any influence on his decision, whether she should or should not handle it.
Could someone see flaws in my arguments? Or are there other criteria, which might me want to use fail instead of raise?
use 'raise' for exceptions to be caught, and 'fail' for serious errors which are not meant to be handled
This is not what the official style guide or the link you provided say on the matter.
What is meant here is use raise only in rescue blocks. Aka use fail when you want to say something is failing and use raise when rethrowing an exception.
As for the "does it matter" part - it is not one of the most hardcore strictly followed rules, but you could make the same argument for any convention. You should follow in that order:
Your project style guide
Your company style guide
The community style guide
Ideally, the three should be the same.
Update: As of this PR (December 2015), the convention is to always use raise.
I once had a conversation with Jim Weirich about this very thing, I have since always used fail when my method is explicitly failing for some reason and raise to re-thrown exceptions.
Here is a post with a message from Jim (almost verbatim to what he said to me in person):
http://www.virtuouscode.com/2014/05/21/jim-weirich-on-exceptions/
Here is the relevant text from the post, a quote attributed to Jim:
Here’s my basic philosophy (and other random thoughts) on exceptions.
When you call a method, you have certain expectations about what the method will accomplish. Formally, these expectations are called post-conditions. A method should throw an exception whenever it fails to meet its postconditions.
To effectively use this strategy, it implies you must have a small understanding of Design by Contract and the meaning of pre- and post-conditions. I think that’s a good thing to know anyways.
Here’s some concrete examples. The Rails model save method:
model.save!
-- post-condition: The model object is saved.
If the model is not saved for some reason, then an exception must be raised because the post-condition is not met.
model.save
-- post-condition: (the model is saved && result == true) ||
(the model is not saved && result == false)
If save doesn’t actually save, then the returned result will be false , but the post-condition is still met, hence no exception.
I find it interesting that the save! method has a vastly simpler post-condition.
On the topic of rescuing exceptions, I think an application should have strategic points where exceptions are rescued. There is little need for rescue/rethrows for the most part. The only time you would want to rescue and rethrow is when you have a job half-way done and you want to undo something so avoid a partially complete state. Your strategic rescue points should be chosen carefully so that the program can continue with other work even if the current operation failed. Transaction processing programs should just move on to the next transaction. A Rails app should recover and be ready to handle the next http request.
Most exception handlers should be generic. Since exceptions indicate a failure of some type, then the handler needs only make a decision on what to do in case of failure. Detailed recovery operations for very specific exceptions are generally discouraged unless the handler is very close (call graph wise) to the point of the exception.
Exceptions should not be used for flow control, use throw/catch for that. This reserves exceptions for true failure conditions.
(An aside, because I use exceptions to indicate failures, I almost always use the fail keyword rather than the raise keyword in Ruby. Fail and raise are synonyms so there is no difference except that fail more clearly communcates that the method has failed. The only time I use raise is when I am catching an exception and re-raising it, because here I’m not failing, but explicitly and purposefully raising an exception. This is a stylistic issue I follow, but I doubt many other people do).
There you have it, a rather rambling memory dump on my thoughts on exceptions.
I know that there are many style guides that do not agree (the style guide used by RoboCop, for example). I don't care. Jim convinced me.

Should Every Stored Procedure Have an Exception Block?

I have a client who runs an Oracle 11 database. The DBA for this client insists that every stored procedure added to the database contain an exception handler (even if the sproc just does a SELECT). Does this make any sense? Our data layer on the web site already has built-in exception handling and logging (which works well). The data layer is written in .NET.
I have told the DBA that an exception handler is only called for when there is some specific action that can be taken in case of an error (like a transaction rollback), or when some predictable error is likely to occur.
He insists that every sproc have an exception block.
Any opinions on whether this is a good or needed practice would be appreciated.
Thanks!
I can't speak to any Oracle-specific need that this may be satisfying. Maybe there's something the DBA knows that we don't?
But, in general, you're correct. An exception handler is needed only where one can meaningfully handle an exception. If there's nothing that can be logically done at that point in the code, then there's no reason to catch an exception. (I wonder... would the DBA's requirement be satisfied if the exception handling block did nothing but re-throw?)
Now, having said that, there's also a certain amount of prudence is following the coding standards set forth by the team which owns a particular system. That is... Is this a fight worth having? (In my own personal and not universally applicable experience, this is a particularly grueling fight with DBAs. Especially DBAs in charge of dinosaurs like Oracle or DB2. But take that with a grain of salt.)
A good compromise in a situation like this would likely be to sit down with the DBA and discuss what he/she expects the exception handler to do. Logically determine, collaboratively, how to meaningfully handle exceptions in this particular stored procedure. The DBA may see that there's less need for it, or conversely you may find a need for it that you hadn't considered. Either way, it's a good opportunity to arrive at an understanding of an otherwise coarsely-expressed blanket rule as it applies to a specific scenario.
This is a similar argument as when to use a checked exception vs. an unchecked exception in Java. It can be a matter of opinion, but it seems to me that a good starting point is what you have already said: catch the exception if there's a way you can deal with it.

Is it easy to abuse the observer pattern?

I have a project where I am using the observer pattern extensively for the first time. One thing I've found though, is that if I inspect a typical object in this project, it tends to be astonishingly large with all of the observers and observables, and then the times when an observer has other observers, etc.
That seems to be be beside the point since the performance is fine. But I've found that occasionally when I'm in the debugger, if I try to print an instance variable that it will lock up my machine until I kill the process. This has me concerned that there is some opportunity for this to happen while the code is in production. Or that this is just a warning that I am abusing the pattern.
Any tips, suggestions?
TL;DR: Yep, but that doesn't mean it's not perfect sometimes.
"Astonishingly large" implies... it's pretty large; what does that actually mean? How many observers/observables are there? Are they deeply nested?
IMO the correlation between doing stuff in a debugger and "real life" isn't particularly strong; has it ever locked up in production or testing? I'd be more likely to think it's an artifact of the debugging process/app.
"Spooky action at a distance" creates non-locality that must be understood in order to reason correctly about code and behavior. This kind of development needs to be groomed aggressively; rather than saying "I'll just create a new observer", architect it in, and keep reasoning as linear as possible.
You could override the inspect method to be less verbose.

How "defensive" should my code be?

I was having a discussion with one of my colleagues about how defensive your code should be. I am all pro defensive programming but you have to know where to stop. We are working on a project that will be maintained by others, but this doesn't mean we have to check for ALL the crazy things a developer could do. Of course, you could do that but this will add a very big overhead to your code.
How do you know where to draw the line?
Anything a user enters directly or indirectly, you should always sanity-check. Beyond that, a few asserts here and there won't hurt, but you can't really do much about crazy programmers editing and breaking your code, anyway!-)
I tend to change the amount of defense I put in my code based on the language. Today I'm primarily working in C++ so my thoughts are drifting in that direction.
When working in C++ there cannot be enough defensive programming. I treat my code as if I'm guarding nuclear secrets and every other programmer is out to get them. Asserts, throws, compiler time error template hacks, argument validation, eliminating pointers, in depth code reviews and general paranoia are all fair game. C++ is an evil wonderful language that I both love and severely mistrust.
I'm not a fan of the term "defensive programming". To me it suggests code like this:
void MakePayment( Account * a, const Payment * p ) {
if ( a == 0 || p == 0 ) {
return;
}
// payment logic here
}
This is wrong, wrong, wrong, but I must have seen it hundreds of times. The function should never have been called with null pointers in the first place, and it is utterly wrong to quietly accept them.
The correct approach here is debatable, but a minimal solution is to fail noisily, either by using an assert or by throwing an exception.
Edit: I disagree with some other answers and comments here - I do not think that all functions should check their parameters (for many functions this is simply impossible). Instead, I believe that all functions should document the values that are acceptable and state that other values will result in undefined behaviour. This is the approach taken by the most succesful and widely used libraries ever written - the C and C++ standard libraries.
And now let the downvotes begin...
I don't know that there's really any way to answer this. It's just something that you learn from experience. You just need to ask yourself how common a potential problem is likely to be and make a judgement call. Also consider that you don't necessarily have to always code defensively. Sometimes it's acceptable just to note any potential problems in your code's documentation.
Ultimately though, I think this is just something that a person has to follow their intuition on. There's no right or wrong way to do it.
If you're working on public APIs of a component then its worth doing a good amount of parameter validation. This led me to have a habit of doing validation everywhere. Thats a mistake. All that validation code never gets tested and potentially makes the system more complicated than it needs to be.
Now I prefer to validate by unit testing. Validation definitely happens for data coming from external sources, but not for calls from non-external developers.
I always Debug.Assert my assumptions.
My personal ideology: the defensiveness of a program should be proportional to the maximum naivety/ignorance of the potential user base.
Being defensive against developers consuming your API code is not that different from being defensive against regular users.
Check the parameters to make sure they are within appropriate bounds and of expected types
Verify that the number of API calls which could be made are within your Terms of Service. Generally called throttling it usually only applies to web services and password checking functions.
Beyond that there's not much else to do except make sure your app recovers well in the event of a problem and that you always give ample information to the developer so that they understand what's going on.
Defensive programming is only one way of hounouring a contract in a design-by-contract manner of coding.
The other two are
total programming and
nominal programming.
Of course you shouldnt defend yourself against every crazy thing a developer could do, but then you should state in wich context it will do what is expected to using preconditions.
//precondition : par is so and so and so
function doSth(par)
{
debug.assert(par is so and so and so )
//dostuf with par
return result
}
I think you have to bring in the question of whether you're creating tests as well. You should be defensive in your coding, but as pointed out by JaredPar -- I also believe it depends on the language you're using. If it's unmanaged code, then you should be extremely defensive. If it's managed, I believe you have a little bit of wiggleroom.
If you have tests, and some other developer tries to decimate your code, the tests will fail. But then again, it depends on test coverage on your code (if there is any).
I try to write code that is more than defensive, but down right hostile. If something goes wrong and I can fix it, I will. if not, throw or pass on the exception and make it someone elses problem. Anything that interacts with a physical device - file system, database connection, network connection should be considered unereliable and prone to failure. anticipating these failures and trapping them is critical
Once you have this mindset, the key is to be consistent in your approach. do you expect to hand back status codes to comminicate problems in the call chain or do you like exceptions. mixed models will kill you or at least drive you to drink. heavily. if you are using someone elses api, then isolate these things into mechanisms that trap/report in terms you use. use these wrapping interfaces.
If the discussion here is how to code defensively against future (possibly malevolent or incompetent) maintainers, there is a limit to what you can do. Enforcing contracts through test coverage and liberal use of asserting your assumptions is probably the best you can do, and it should be done in a way that ideally doesn't clutter the code and make the job harder for the future non-evil maintainers of the code. Asserts are easy to read and understand and make it clear what the assumptions of a given piece of code is, so they're usually a great idea.
Coding defensively against user actions is another issue entirely, and the approach that I use is to think that the user is out to get me. Every input is examined as carefully as I can manage, and I make every effort to have my code fail safe - try not to persist any state that isn't rigorously vetted, correct where you can, exit gracefully if you cannot, etc. If you just think about all the bozo things that could be perpetrated on your code by outside agents, it gets you in the right mindset.
Coding defensively against other code, such as your platform or other modules, is exactly the same as users: they're out to get you. The OS is always going to swap out your thread at an inopportune time, networks are always going to go away at the wrong time, and in general, evil abounds around every corner. You don't need to code against every potential problem out there - the cost in maintenance might not be worth the increase in safety - but it sure doesn't hurt to think about it. And it usually doesn't hurt to explicitly comment in the code if there's a scenario you thought of but regard as unimportant for some reason.
Systems should have well designed boundaries where defensive checking happens. There should be a decision about where user input is validated (at what boundary) and where other potential defensive issues require checking (for example, third party integration points, publicly available APIs, rules engine interaction, or different units coded by different teams of programmers). More defensive checking than that violates DRY in many cases, and just adds maintenance cost for very little benifit.
That being said, there are certain points where you cannot be too paranoid. Potential for buffer overflows, data corruption and similar issues should be very rigorously defended against.
I recently had scenario, in which user input data was propagated through remote facade interface, then local facade interface, then some other class, to finally get to the method where it was actually used. I was asking my self a question: When should be the value validated? I added validation code only to the final class, where the value was actually used. Adding other validation code snippets in classes laying on the propagation path would be too defensive programming for me. One exception could be the remote facade, but I skipped it too.
Good question, I've flip flopped between doing sanity checks and not doing them. Its a 50/50
situation, I'd probably take a middle ground where I would only "Bullet Proof" any routines that are:
(a) Called from more than one place in the project
(b) has logic that is LIKELY to change
(c) You can not use default values
(d) the routine can not be 'failed' gracefully
Darknight

Error Message Text - Best Practices

We are changing some of the text for our old, badly written error messages. What are some resources for best practices on writing good error messages (specifically for Windows XP/Vista).
In terms of wording your error messages, I recommend referring to the following style guides for Windows applications:
Windows user experience guidelines, and specifically the section on error messages here.
Microsoft Manual of Style
The ultimate best practice is to prevent the user from causing errors in the first place.
Don't tell users anything they don't care about; error code 5064 doesn't mean a thing to anyone. Don't tell them they did something wrong; disallow it in the first place. Don't blame them, especially not for mistakes your software made. Above all, when there is a problem, tell them how to fix it so they can move on and get some work done.
A good error message should:
Be unobtrusive (no blue-screen or yellow-screen of death)
Give the user direction to correct the problem (on their own if possible, or who to contact for help)
Hide useless, esoteric programmer nonsense ( don't say, "a null reference exception occurred on line 45")
Be descriptive without being verbose. Just enough information to tell the user what they need to know and nothing more.
One thing I've started to do is to generate a unique number that I display in the error message and write to the log file so I can find the error in the log when the user sends me a screenshot or calls and says, "I got an error. It says my reference number is 0988-7634"
For security reasons, don't provide internal system information that the user does not need.
Trivial example: when failing to login, don't tell the user if the username is wrong or the password is wrong; this will only help the attacker to brute force the system. Instead, just say "Username/Password combination is invalid" or something like that.
Always include suggestions to Remedy the error.
Try to figure out a way to write your software so it corrects the problem for them.
For any user input (strings, filenames, values, etc), always display the erroneous value with delimiters around it (quotes, brackets, etc). e.g.
The filename you entered could not be found: "somefile.txt"
This helps to show any whitespace/carriage returns that may have sneaked in and greatly reduces troubleshooting and frustration.
Avoid identical error messages coming from different places; parametrize with file:line if possible, or use other context that lets you, the developer, uniquely identify where the error occurred.
Design the mechanism to allow easy localization, especially if it is a commercial product.
If the error messages are user-visible, make them complete, meaningful sentences that don't assume intimate knowledge of the code; remember, you're always too close to the problem -- the user is not. If possible, give the user guidance on how to proceed, who to contact, etc.
Every error should have a message if possible; if not, then try and make sure that all error-unwind paths eventually reach an error message that sheds light on what happened.
I'm sure there will be other good answers here...
Shorter messages may actually be read.
The longer your error message, the less the user will read. That being said, try to refactor the code so you can eliminate exceptions if there is an obvious response. Try to only have exceptions that happen based on things beyond your user or your code's control.
The best exception message is the one you never have to display.
Error handling is always better than error reporting, but since you are retrofitting the error messages and not necessarily the code here's a couple of suggestions:
Users want solutions, not problems. Help them know what to do after an error, even if the message is as simple as "Please close the current window and retry your action."
I am also a big fan of centralized logging of errors. Make sure the log is both human and computer scanable. Users don't always let you know what problems they are having, especially if they can be 'worked around', so the log can help you know what things need fixed.
If you can control the error dialog easily, having a dialog which shows a nice, readable message with a 'details' button to show the error number, trace, etc. can be a big help for real-time problem solving as well.
Support for multilanguage applies for all kinds of messages, but tends to be forgotten in the case of error messages.
I would second not telling the user useless esoteric information like numeric error codes. I would follow that up however by saying to definitely log that information for troubleshooting by more technically savvy people.

Resources