How to return often occurring error in object oriented environment? - oop

assume you have a function that polls some kind of queue and blocks for a certain amount of time. If this time has passed without something showing up on the queue, some indication of the timeout should be delivered to the caller, otherwise the something that showed up should be returned.
Now you could write something like:
class Queue
{
Thing GetThing();
}
and throw an exception in case of a timeout. Or you
write
class Queue
{
int GetThing(Thing& t);
}
and return an error code for success and timeout.
However, drawback of solution 1 is that the on a not so busy queue timeout is not an exceptional case, but rather common. And solution 2 uses return values for errors and ugly syntax, since you can end up with a Thing that contains nothing.
Is there another (smart) solution for that problem? What is the preferred solution in an object oriented environment?

I would use exceptions only when the error is serious enough to stop the execution of the application, or of any big-enough application's component. But I wouldn't use exceptions for common cases, after which we continue the normal execution or execute the same function again. This would be just using exceptions for flow control, which is wrong.
So, I suggest you to either use the second solution that you proposed, or to do the following:
class Queue
{
bool GetThing(Thing& t); // true on success, false on failure
string GetLastError();
};
Of course you can stick with an int for an error code, instead of a string for the full error message. Or even better, just define class Error and have GetLastError() return it.

Why not just return null from GetThing in your first solution, changing it to return a Thing *? It seems to fit the bill, at least from the information you've given so far.

In the first, and second case, you can't do anything but throw an exception. When you return a Thing, or a Thing&, you don't have the option of not returning a Thing.
If you want to fail without using an exception then you need:
class Queue
{
// Either something like this. GetThing retuns NULL on an error,
// GetError returns a specific error code
Thing* GetThing();
int GetError();
// This kind of pattern is common. Return a result code
// and set ppOut to a valid thing or NULL.
int GetThing(Thing** ppOut);
};

Related

How to handle a forEach loop that returns early based on an enum except for one path in Kotlin

We have an API service call that returns a bunch of validation messages. In each message there is a string that contains an error code.
Our implementation converts the validation string into an enum value and then we process the enumeration as there are some error code we just don't care about.
The question becomes, how to handle the loop of messages in a Kotlin way:
response.validationErrors?.forEach {
val mediaFailure = decodeValidationMessage(it.message)
if (mediaFailure != MediaFailure.Unknown) {
return when (mediaFailure) {
MediaFailure.Encrypted -> DomainResponse(ErrorReasonCode.ERR_DOCUMENT_ENCRYPTED)
MediaFailure.NotSupported -> Response.validationFailed()
MediaFailure.InternalError -> Response.serviceFailed()
else -> throw NotImplementedError()
}
}
}
Here we loop through all the messages, then once the message error is not "Unknown" it returns the necessary response to the caller.
However, IntelliJ wants the else path, even though the if prevents that from happening.
Is there a proper Kotlin way of implementing this kind of loop?
From what I understood, you want to return a response for the first mediaFailure which is not MediaFailure.Unknown and you don't want that throw NotImplementedError() part in your function.
One way to fix this is to remove the if condition and continue the forEach loop when MediaFailure.Unknown is found.
response.validationErrors?.forEach {
val mediaFailure = decodeValidationMessage(it.message)
return when (mediaFailure) {
MediaFailure.Encrypted -> DomainResponse(ErrorReasonCode.ERR_DOCUMENT_ENCRYPTED)
MediaFailure.NotSupported -> Response.validationFailed()
MediaFailure.InternalError -> Response.serviceFailed()
MediaFailure.Unknown -> return#forEach // continue the loop
}
}
I think this is one of the many cases when it pays to step back from the code a bit and try to look at the big picture. To ask “What's the ultimate goal here? What am I trying to achieve with this code?”
(In traditional, lower-level languages, almost anything you want to do with a list or array requires a loop, so you get into the habit of reaching for a for or while without thinking. But there are often alternative approaches in Kotlin that can be more concise, clearer, and harder to get wrong. They tend to be more about what you're trying to achieve, rather than how.)
In this case, it looks you want to find the first item which decodes to give a known type (i.e. not MediaFailure.Unknown), and return a value derived from that.
So here's an attempt to code that:
val message = response.validationErrors?.asSequence()
?.map{ decodeValidationMessage(it.message) }
?.firstOrNull{ it != MediaFailure.Unknown }
return when (message) {
MediaFailure.Encrypted -> DomainResponse(ErrorReasonCode.ERR_DOCUMENT_ENCRYPTED)
MediaFailure.NotSupported -> Response.validationFailed()
MediaFailure.InternalError, null -> Response.serviceFailed()
else -> throw NotImplementedError()
}
This is still fairly similar to your code, and it's about as efficient. (Thanks to the asSequence(), it doesn't decode any more messages than it needs to.) But the firstOrNull() makes clear what you're looking for; and it's obvious that you go on to process only that one message — a fact which is rather lost in the original version.
(If there are no valid messages, message will be null and so this will return serviceFailed(), as per comments.)
There are of course many ways to skin a cat, and I can think of several variations. (It's often a worthwhile exercise to come up with some — if nothing else, it gives you more confidence in the version you end up with!) Try to pick whichever seems clearest, simplest, and best matches the big picture of what you're doing; that tends to work out best in the long run.

How to do a fail fast in Kotlin properly?

I want to fail fast if a specific function is returning null. I have no case where default value would make processing meaningful.
This is the snippet:
val entityAttributes = entity.optJSONObject("Attributes") ?: run {
LOG.error("Could not find 'Attribute' entry in Entity object")
return
}
So if entity.optJSONObject("Attributes") returns null (which it does desipite the opt*) I want to escape from the function scope.
Is the way I did it the proper one? I am fairly new to Kotlin and want to get used to the proper ways of doing these things as early as possible.
You can return from the function early like you do above. If your function returns something besides Unit, then you'd have to return some default value.
Throwing an exception allows you to exit a function without returning anything, but the exception will crash the program if you don't catch it somewhere. Sometimes this is exactly what you want to happen if the error is something that should never happen, because then you'll catch it during testing and be able to fix it before releasing your application.
Use the global error(cause: Any) function and it will immediately throw an IllegalStateException.

Fail safe assertions in Swift

I commonly use assertions in Objective-C where I want to assert a value. On a debug build I assert in order to stop execution of the program and check if my assumption was incorrect. However, on production builds I find a way to fail safely in a way to minimise the user impact. I achieve this by creating a macro that encapsulates an NSAssert within an if statement which also executes the code I would like to run as a failsafe on production. For example:
An assertion macro I would use:
#define AssertTrueOrExecute(condition, action) \
if (!condition) { \
NSAssert(testCondition, #"Condition failed"); \
action; \
}
Somewhere in my application I would have something like this:
- (void)someMethod
{
BOOL testCondition = ...
// Ensure the testCondition is true before proceeding any further
AssertTrueOrExecute(testCondition, return);
// Potentially unsafe code that never gets executed if testCondition is false
}
- (void)someReturningMethod
{
BOOL testCondition = ...
// Ensure the testCondition is true before proceeding any further
AssertTrueOrExecute(testCondition, return #"safe string");
// Potentially unsafe code that never gets executed if testCondition is false
}
Since I cannot define a macro like the one mention in Swift, is there a way to have the same behaviour? That is how would I go about having a Swift equivalent for my AssertTrueOrExecute macro?
Update:
To further explain the question, if I was using Swift I currently would write something like this:
func someMethod () {
let testCondition : Bool = ...
// Ensure the testCondition is true before proceeding any further
if (!testCondition) {
assert(testCondition);
return;
}
// Potentially unsafe code that never gets executed if testCondition is false
}
So the question is more along the lines of how can the if statement with the assertions be wrapped in a similar way I have the Objective-C macro so that I can assert or return early for example?
Update 2:
Another example would be in function that returns something, for example:
func someReturningMethod () -> String {
let testCondition : Bool = ...
// Ensure the testCondition is true before proceeding any further
if (!testCondition) {
assert(testCondition);
return "safe string";
}
// Potentially unsafe code that never gets executed if testCondition is false
return "some other string"
}
There are no macros in Swift, but there could be other means in Swift where you could achieve this same functionality as it is possible in Objective-C.
However, the real issue here is, that you try to approach a problem in a way which you really shouldn't:
Do not mix programmer errors and runtime errors!
Instead, make a clear distinction what programmer errors are and what runtime errors are. Handle programmer errors with assertions, and handle runtime errors with NSError respectively in Swift with try & catch and throw.
Note, that the "scope" of a programmer error is not restricted to the point when the program fails through an assertion failure: Very likely such an error has bad side effects which leave the program in an invalid state, and often this assertion detects errors that may have occurred possibly a long time before the assertion failed. So, when an assertion fails, your program is very likely already in an invalid state.
A rule of thumb is, that an assertion failure should not happen in production code (read MUST NOT). Well, these are programmer errors and should be fixed, shouldn't they? You verify your assumptions using assertions in unit tests. If you still fear, that your assumption may break in production and are also sure that this is not a runtime error (which should always be handled gracefully), it should stop the program - all bets are off anyway. In Swift, you can use fatalError for this.
Sometimes, the distinction whether the violation of a certain assumption is a programmer error or whether it's a runtime error is not always that obvious and may depend on the context. As a programmer, though, you can always define what it is. Take a string parameter as example: if you obtain it directly from a text field from a user input who wants to create an account and is asked for his name, you should validate the string and return/throw an error if it doesn't fit your expectation - for example if it is empty, too short etc. That is, in Swift you may throw an error and handle that gracefully on the call-site, possibly in a View Controller. On the other hand, you define that it would not make sense to initialise a User object whose name will be empty. That is, in your init routine you define the precondition that a valid user name must not be empty, and you check this with assert or fatalError. In this scenario your program is correct, when there is no code path which initialises a User whose name is empty.

How to do error handling in Rust and what are the common pitfalls?

I noticed that Rust does not have exceptions. How to do error handling in Rust and what are the common pitfalls? Are there ways to control flow with raise, catch, reraise and other stuff? I found inconsistent information on this.
Rust generally solves errors in two ways:
Unrecoverable errors. Once you panic!, that's it. Your program or thread aborts because it encounters something it can't solve and its invariants have been violated. E.g. if you find invalid sequences in what should be a UTF-8 string.
Recoverable errors. Also called failures in some documentation. Instead of panicking, you emit a Option<T> or Result<T, E>. In these cases, you have a choice between a valid value Some(T)/Ok(T) respectively or an invalid value None/Error(E). Generally None serves as a null replacement, showing that the value is missing.
Now comes the hard part. Application.
Unwrap
Sometimes dealing with an Option is a pain in the neck, and you are almost guaranteed to get a value and not an error.
In those cases it's perfectly fine to use unwrap. unwrap turns Some(e) and Ok(e) into e, otherwise it panics. Unwrap is a tool to turn your recoverable errors into unrecoverable.
if x.is_some() {
y = x.unwrap(); // perfectly safe, you just checked x is Some
}
Inside the if-block it's perfectly fine to unwrap since it should never panic because we've already checked that it is Some with x.is_some().
If you're writing a library, using unwrap is discouraged because when it panics the user cannot handle the error. Additionally, a future update may change the invariant. Imagine if the example above had if x.is_some() || always_return_true(). The invariant would changed, and unwrap could panic.
? operator / try! macro
What's the ? operator or the try! macro? A short explanation is that it either returns the value inside an Ok() or prematurely returns error.
Here is a simplified definition of what the operator or macro expand to:
macro_rules! try {
($e:expr) => (match $e {
Ok(val) => val,
Err(err) => return Err(err),
});
}
If you use it like this:
let x = File::create("my_file.txt")?;
let x = try!(File::create("my_file.txt"));
It will convert it into this:
let x = match File::create("my_file.txt") {
Ok(val) => val,
Err(err) => return Err(err),
};
The downside is that your functions now return Result.
Combinators
Option and Result have some convenience methods that allow chaining and dealing with errors in an understandable manner. Methods like and, and_then, or, or_else, ok_or, map_err, etc.
For example, you could have a default value in case your value is botched.
let x: Option<i32> = None;
let guaranteed_value = x.or(Some(3)); //it's Some(3)
Or if you want to turn your Option into a Result.
let x = Some("foo");
assert_eq!(x.ok_or("No value found"), Ok("foo"));
let x: Option<&str> = None;
assert_eq!(x.ok_or("No value found"), Err("No value found"));
This is just a brief skim of things you can do. For more explanation, check out:
http://blog.burntsushi.net/rust-error-handling/
https://doc.rust-lang.org/book/ch09-00-error-handling.html
http://lucumr.pocoo.org/2014/10/16/on-error-handling/
If you need to terminate some independent execution unit (a web request, a video frame processing, a GUI event, a source file to compile) but not all your application in completeness, there is a function std::panic::catch_unwind that invokes a closure, capturing the cause of an unwinding panic if one occurs.
let result = panic::catch_unwind(|| {
panic!("oh no!");
});
assert!(result.is_err());
I would not grant this closure write access to any variables that could outlive it, or any other otherwise global state.
The documentation also says the function also may not be able to catch some kinds of panic.

Should out params be set even if COM function fails?

When implementing a COM interface I always assign to the out parameters on success but should I do so also on error?
HRESULT CDemo::Div(/*[in]*/ LONG a, /*[in]*/LONG b, /*[out,retval]*/ LONG* pRet)
{
if (pRet == NULL)
return E_POINTER;
if (b == 0)
{
*pRet = 0; // is this redundant?
return E_INVALIDARG;
}
*pRet = a/b;
return S_OK;
}
At one time I was bit on the nose by not initializing an out parameter and assuming that if I initialized the variable it will remain that value if I don't change it inside the method. However I used this method from .NET and since the marshaller sees that this is an [out] parameter it discarded the initial value I placed on the call site and put in garbage after the function returned (it was fun debugging that, not).
Is assigning to an out param even on failure overcompensation or should I really do it?
Edit: Even though formally one should not access out params if the function failed I often see (and sometimes write) code like this (using the example from sharptooth's post):
ISmth *pSmth = NULL;
pObj->GetSmth(&pSmth); // HRES is ignored
if (pSmth) // Assumes that if GetSmth failed then pSmth is still NULL
{
pSmth->Foo();
pSmth->Release();
}
This works fine in un-marshalled code (same thread apartment) but if a marshaller is involved is it smart enough to only set the return value if the function succeeded?
While the other answers are not wrong, they miss a very important point -- a COM server that intends to return a failure HRESULT MUST set all [out] parameters to NULL. This is not merely a matter of good style, it is required by COM and not adhering to it can cause random crashes when there is marshaling involved.
That said, the *pRet = 0; in the original code is not redundant but correct and required.
The rule is that the calling party is not allowed to do anything with the out parameters value if the call fails. The server therefore should not provide valid values and should not pass ownership of any resources to the out parameters.
For example if you have
HRESULT GetSmth( [out] ISmth** );
method then it's expected that the server calls AddRef() on the ISmth** variable prior to returning. It must not call AddRef() if it is going to return a failure code because the client is not allowed to use the returned out parameter value and therefore will not call Release() and you'll get a memory leak.
I'm not sure I 100% agree with sharptooth. I certainly agree that for a failed COM call you cannot and must not assign any resource ownership to any out parameters. This includes memory allocation or AddRef'ing a COM object.
However I see nothing wrong (and in fact encourage) setting purely out parameters to empty values as long is does not transfer any resource ownership. For instance there is nothing technically illegal about your code setting pRet to point to 0. This transfers no resource ownership over to pRet and is merely a helper to some caller who did not properly check for success of the call.