Kotlin - Document exception thrown by an interface method - kotlin

Since Kotlin hasn't got checked exception, what's the correct way to document exception expected to be thrown by an interface method? Should I document it in the interface or in the implementing class (only if the concrete method actually throws it)?

Since clients program against the interface, I'd suggest the documentation to be made in the Javadoc/KDoc of that interface. Whether you actually should document them is discussed in this thread for example:
Oracle recommends:
If it's so good to document a method's API, including the exceptions it can throw, why not specify runtime exceptions too? Runtime exceptions represent problems that are the result of a programming problem, and as such, the API client code cannot reasonably be expected to recover from them or to handle them in any way. Such problems include arithmetic exceptions, such as dividing by zero; pointer exceptions, such as trying to access an object through a null reference; and indexing exceptions, such as attempting to access an array element through an index that is too large or too small. Runtime exceptions can occur anywhere in a program, and in a typical one they can be very numerous. Having to add runtime exceptions in every method declaration would reduce a program's clarity.
So if the information is useful for a client it should be documented (i.e. if the client can handle it, e.g. IOException). For "regular" runtime exceptions such as an IllegalArgumentException I would say "no", do not document them.

Related

Does the ABI persist any more error information than an HRESULT?

While porting a regular C++ class to a Windows Runtime class, I hit a fairly significant road block. My C++ class reports certain error conditions by throwing custom error objects. This allows clients to conveniently filter on exceptions, documented in the public interface.
I cannot seem to find a reliable way to pass enough information across the ABI to replicate the same fidelity1 using the Windows Runtime. Under the assumption, that an HRESULT is the only generalized error reporting information, I have evaluated the following options:
The 'obvious' choice: Map the exception condition to any of the predefined HRESULT values. While this technically works (presumably), there is no way at the call site to distinguish between errors originating from the implementation, and errors originating from callees of the implementation.
Invent custom HRESULTs. If this layout still applies to the Windows Runtime, I could easily set the Customer bit and go crazy with my 27 bits worth of error code representation. This works, until someone else does the same. I'm not aware of any way to attribute an HRESULT to an interface, which would solve this ambiguity.
Even if either of the above could be made to work as intended, throwing hresult_errors as prescribed, the call site would still be at the mercy of the language projection. While C# seemingly allows to pass any System.Exception(-derived) error object across the ABI, and have them re-thrown at the call site, C++/WinRT only supports some 14 distinct exception types (see throw_hresult).
With neither of these options allowing for sufficiently complete error information to cross the ABI, it seems that an HRESULT simply may not be enough. Does the Windows Runtime have any provisioning to allow for additional (arbitrary) error information to cross the ABI?
1 I'm not strictly interested in passing actual C++ exceptions across. Instead, I'm looking for a way to allow clients to uniquely identify documented error conditions, in a natural way. Passing custom Windows Runtime error types would be fine.
There are a few options here. Our general API guidance for Windows Runtime APIs that have well-defined, expected failure modes is that failure information should be part of the normal parameters and return value. We would normally create a TryDoSomething API in this situation and provide extended error information via either a return or out parameter. This works best for us due to the fact that there's no consistent way to map exceptions across all languages. This is a topic we hope to revisit more in xlang in the future.
HRESULTs are usable with a caveat. HRESULT values can be a nuisance in anything but C++, where you need to redefine them locally because you can't just use the header. They will generate exceptions in most languages, so if this is common, you'll be creating debugger noise for your components' clients.
The last option allows you to transit a language-specific exception stored in a COM object across the ABI boundary (and up the COM logical stack, including across marshalled calls). In practice it will only be usable by C++ code compiled with the same compiler, settings, and type definitions as the component itself. E.g. passing it from a component compiled with VC to a component compiled with Clang could potentially lead to memory corruption.
Assuming I haven't scared you off, you'll want to look at RoOriginateLanguageException. It allows you to wrap the exception in a COM object and store it with other winrt error data in the TLS. We use this in projections to enable exceptions thrown within a callback to propagate to the outer code using the same projection in a controlled way that unwinds safely through other code potentially written using other languages or tools. This is how the support in C# and other languages is implemented.
Thanks,
Ben

Is there an efficient way to avoid instantiating a class with syntax errors?

As you may know, it is pretty easy to have active code of a class containing syntax errors (someone activated the code ignoring syntax warnings or someone changed the signature of a method the class calls, for instance).
This means that also dynamic instantiation of such a class via
CREATE OBJECT my_object TYPE (class_name).
will fail with an apparently uncatchable SYNTAX_ERROR exception. The goal is to write code that does not terminate when this occurs.
Known solutions:
Wrap the CREATE OBJECT statement inside an RFC function module, call the module with destination NONE, then catch the (classic) exception SYSTEM_FAILURE from the RFC call. If the RFC succeeds, actually create the object (you can't pass the created object out of the RFC because RFC function modules can't pass references, and objects cannot be passed other than by reference as far as I know).
This solution is not only inelegant, but impacts performance rather harshly since an entirely new LUW is spawned by the RFC call. Additionally, you're not actually preventing the SYNTAX_ERROR dump, just letting it dump in a thread you don't care about. It will still, annoyingly, show up in ST22.
Before attempting to instantiate the class, call
cl_abap_typedescr=>describe_by_name( class_name )
and catch the class-based exception CX_SY_RTTI_SYNTAX_ERROR it throws when the code it attempts to describe has syntax errors.
This performs much better than the RFC variant, but still seems to add unnecessary overhead - usually, I don't want the type information that describe_by_name returns, I'm solely calling it to get a catchable exception, and when it succeeds, its result is thrown away.
Is there a way to prevent the SYNTAX_ERROR dump without adding such overhead?
Most efficient way we could come up with:
METHODS has_correct_syntax
IMPORTING
class_name TYPE seoclsname
RETURNING
VALUE(result) TYPE abap_bool.
METHOD has_correct_syntax.
DATA(include_name) = cl_oo_classname_service=>get_cs_name( class_name ).
READ REPORT include_name INTO DATA(source_code).
SYNTAX-CHECK FOR source_code MESSAGE DATA(message) LINE DATA(line) WORD DATA(word).
result = xsdbool( sy-subrc = 0 ).
ENDMETHOD.
Still a lot of overhead for loading the program and syntax-checking it. However, at least none additional for compiling descriptors you are not interested in.
We investigated when we produced a dependency manager that wires classes together upon startup and should exclude syntactically wrong candidates.
CS includes don't always exist, so get_cs_name might come back empty. Seems to depend on the NetWeaver version and the editor the developer used.
If you are certain that the syntax errors are caused by the classes’ own code, you might want to consider buffering the results of the syntax checks and only revalidate when the class changed after it was last checked. This does not work if you expect syntax errors to be caused by something outside those classes.

Etiquette of error codes in COM

In a COM object generally there are two ways of indicating that a function failed (that I'm aware of):
return S_OK and have an [out] parameter to give failure info
return a failure HRESULT, and use ICreateErrorInfo to set the info.
Currently what I am doing is using the failure-HRESULT method for failures that are "really bad", i.e. my object will be basically inoperable because this function failed. For example, unable to open its configuration file.
Is this correct, or should failure HRESULTs be reserved only for things like dispatch argument type mismatches?
The short version:
In COM you should use HRESULTs (and strive to use ISupportErrorInfo, etc.) for most/all types of error conditions. The HRESULT mechanism should be viewed as a form of exception throwing. If you are familiar with that, consider "Error conditions" as anything for which you would normally throw an exception in a language that supports them. Use custom return values for things for which you would not normally use exceptions.
For example, use a failure HRESULT for invalid parameters, invalid sequence of operations, network failures, database errors, unexpected conditions such as out-of-memory, etc. On the other hand, use custom out parameters for things like 'polling, data is not ready yet', EOF conditions, maybe 'checked data and it doesn't pass validations'. There is plenty of discussions out there discussing what each should be (e.g. Stroustrup's TC++PL). The specifics will heavily depend on your particular object's semantics.
The longer version:
At a fundamental level, the COM HRESULT mechanism is just an error code mechanism which has been standardized by the infrastructure. This is mostly because COM must support a number of features such as inter-process (DCOM) and inter-threaded (Apartments) execution, system managed services (COM+), etc. The infrastructure has a need to know when something has failed, and it has a need to communicate to both sides its own infrastructure-related errors. Everybody needs to agree on how to communicate errors.
Each language and programmer has a choice of how to present or handle those errors. In C++, we typically handle the HRESULTs as error codes (although you can translate them into exceptions if you prefer error handling that way). In .NET languages, failure HRESULTs are translated into exceptions because that's the preferred error mechanism in .NET.
VB6 supports "either". Now, I know VB6's so-called exception handling has a painful syntax and limited scoping options for handlers, but you don't have to use it if you don't want to. You can always use ON ERROR RESUME NEXT and do it by hand if you think the usage pattern justifies it in a specific situation. It's just that instead of writing something like this:
statusCode = obj.DoSomething(param1)
If IS_FAILURE(statusCode) Then
'handle error
End If
Your write it like this:
ON ERROR RESUME NEXT
...
obj.DoSomething param1
IF Error.Number <> 0 Then
'handle error
End If
VB6 is simply hiding the error code return value from the method call (and allowing the object's programmer to substitute it for a "virtual return value" via [retval]).
If you make up your own error reporting mechanism instead of using HRESULTs, you will:
Spend a lot of time reinventing a rich error reporting mechanism that will probably mirror what ISupportsErrorInfo already gives you (or most likely, not provide any rich error information).
Hide the error status from COM's infrastructure (which might or might not matter).
Force your VB6 clients to make one specific choice out of the two options they have: they must do explicit line-by-line check, or more likely just ignore the error condition by mistake, even if they would prefer an error handler.
Force your (say) C# clients to handle your errors in ways that runs contrary to the natural style of the language (to have to check every method call explicitly and... likely throw an exception by hand).

How are try/catch blocks implemented?

If an exception occurs in a try block, how is execution transferred to the catch block? This is not a C#/Java/C++ question, I'm just wondering how it works internally.
this is not a c#/java/c++ question. How it works internally,how the line knows to go catch statement.
How this works internally makes this pretty much a c#/java/C++ question (because it will be implemented differently).
In Java, a try block installs itself into a special table (in the class file). When the JVM throws an exception, it looks at that table to see where the next catch or finally block to go to is.
When an exception occurs a special instruction is executed (usually called interrupt). This leads to executing a generic error handler that deduces which is the latest installed suitable exception handler. That handler is then executed.
There is a difference how exceptions are technically handled between natively compiled languages such as C++ and languages using byte-code being executed on a virtual machine such as Java or C#.
C++ compilers usually generate code that protocols the information needed for exception handling at runtime. A dedicated data structure is used to remember entrance/exit of try blocks and the associated exception handler. When an exception occurs, an interrupt is generated and control is passed to the OS which in turn inspects the call stack and determines which exception handler to call.
Further details are pretty well explained in the following article by Vishal Kochhar:
How a C++ compiler implements exception handling
In Java or .NET there is no need for the overhead of maintaining exception handling information as the runtime will be able to introspect the byte code to find the relevant exception handler. As a consequence, only exceptions that are actually thrown are causing an overhead.
It is basically parsing fundamentals of the language.
You can get all info at Here
it should work in all langues somewhat like this:
if (error_occured xy while doing things in try){
call_catch_part(error xy)
}
you could do the same in C even though there is no exception handling per se.
There you would use setjmp/longjmp unfortunately you then do not get the stack unwinding and have to handle all the nitty-gritty yourself.

C++\CLI exception specification not allowed

I'm an experienced unmanaged C++ developer, new to C++\CLI.
How come managed C++ doesnt allow exception specification?
Example link
What's the best practice for specifying exceptions my methods throw then?
Presumably because the CLR doesn't use exception specifications; this in turn is presumably because Microsoft looked at Java and decided that they are far more trouble than they are worth.
So the best practice for specifying what exceptions your methods throw is to not bother, ie remove your exception specs. It's worth pointing out that even in the normal C++ (ie native) world most people either eschew exception specifications entirely, or only use the empty specification to indicate that the method does not throw.