Giter Site home page Giter Site logo

"Use unchecked exceptions" about styleguides HOT 31 OPEN

sap avatar sap commented on June 11, 2024
"Use unchecked exceptions"

from styleguides.

Comments (31)

HrFlorianHoffmann avatar HrFlorianHoffmann commented on June 11, 2024 3

Confirmed this with the ABAP language group. In response to repeated feedback, including our prior discussion of this issue, they added the possibility to declare cx_no_check exceptions in raising clauses. This is available from AS ABAP 7.78/7.55 on. The documentation is behind schedule, so this new feature is not documented, yet.

from styleguides.

jrgkraus avatar jrgkraus commented on June 11, 2024 2

Today I decided to switch back to checked exceptions after having used unchecked exceptions for a while (as a consequence of R. Martins recommendation in Clean Code).

The reason is more pragmatic than conceptual: I just caused too much dumps because I was not aware of possible exceptions when reusing methods. To me, the problem is, that one does not see the possible exceptions in the signature of a method called and without a deeper look at the reused coding the danger of provocation of aborts is too big

from styleguides.

pokrakam avatar pokrakam commented on June 11, 2024 2

I do not know since which version supported this first. The documentation is updated since version 7.55:

This was introduced with 7.55, there is a small blog about it here:
Declaration of CX_NO_CHECK Exception in Raising Clause

Of particular interest is the bit:
This allows it to document the possible occurrence of such exceptions and to change the category of existing exceptions into CX_NO_CHECK without causing errors in interface definitions.
I do like the idea of changing exception types and not having to refactor everything in one go.

from styleguides.

westerholz avatar westerholz commented on June 11, 2024 2

From my point of view the section needs adaptation. It is currently even not in line with the content of the book. The chapter in exceptions contains in the summary this recommendation:


- Create your own exception superclass.
- Raise CX_NO_CHECK exceptions internally.
- Raise CX_STATIC_CHECK exceptions externally.

This is supporting the approach @niuniuch uses: In larger systems you want to use unchecked exceptions internally and checked exceptions for external facing interfaces. What is considered external can deviate based on the environment.
Then working in larger system I think an own exception superclass (inheriting from cx_no_check) can improve error handling. There is more control and for general handling only one exception type needs attention. Still it allows more specific exceptions with further subclasses.

As discussed earlier in this thread: if it is possible, the exceptions should be added in the raising section to add transparency.

from styleguides.

jordao76 avatar jordao76 commented on June 11, 2024 1

I still would recommend using cx_no_check. Just document the exceptions with ABAP doc. There's no need to declare them in the raising clause.

from styleguides.

ConjuringCoffee avatar ConjuringCoffee commented on June 11, 2024 1

I'd like to come back to this topic, specifically this section: https://github.com/SAP/styleguides/blob/main/clean-abap/sub-sections/Exceptions.md#why-cx_no_check-doesnt-help

cx_no_check also doesn't help. Although it makes the method bodies work, the METHODS lower_method definition now is no longer allowed to declare /clean/flexible_exception and compilation fails with a syntax error.

This is not true for newer versions anymore. Exceptions inheriting from CX_NO_CHECK can be declared in method signatures. Doing so does not cause a syntax error anymore.

I do not know since which version supported this first. The documentation is updated since version 7.55:

Both to support the category change of an existing exception and to document the possible occurrence of exceptions of this category, exceptions of category CX_NO_CHECK may also be declared explicitly in procedure interfaces.

If we follow the reasoning of Exceptions.md, then CX_NO_CHECK should be the preferred exception type. If CX_NO_CHECK still should not be recommended, then the section should be updated with the new reasons accordingly.

from styleguides.

niuniuch avatar niuniuch commented on June 11, 2024 1

On the other hand, how do you handle the static check errors on the API consumer side? You don't want to directly use them as they'd force you to declare and propagate as well since they are checked. Do you wrap those there inside of CX_NO_CHECK exceptions again until another API facade is reached?

Correct. In general it's a good architectural principle to have a thin adapter layer on the API's you consume - so you can mock it for automated testing, translate input/outputs, etc. You just put the exception wrapping there.

from styleguides.

HrFlorianHoffmann avatar HrFlorianHoffmann commented on June 11, 2024

From my point of view, Clean Code’s recommendation makes perfect sense ... for Java. Unfortunately, unchecked exceptions behave differently in Java and in ABAP. Let’s go through the motions:

Imagine you have a METHODS read_file with an IMPORTING file_name TYPE string and a RETURNING VALUE(content) TYPE string. Now, obviously, you’d like to inform callers if the file name they’re giving you is wrong. You’ll be throwing an exception for that.

But which kind of exception will it be? A CX_BAD_FILE_NAME, a CX_FILE_NOT_FOUND, or a CX_ILLEGAL_ARGUMENT? All of them sound plausible, and the caller cannot guess which one it will be.

Of course you could expect the caller to read your source code to figure out which exceptions your code will be throwing. But that’s nonsense, right? We don’t want to force callers to reverse-engineer our code to understand what’s going on.

We could also add a documentation, description, comment, or the like, that informs our callers that we will throw CX_FILE_NOT_FOUND. But comments are weak, unreliable things, and surely we’d want something stronger, more reliable, that enables our callers to find out errors at design time, not too late at runtime.

In essence, what we’d like to do is simply adding the clause THROWING cx_file_not_found to our method declaration. And this is exactly where CX_NO_CHECK falls apart: ABAP does not allow you to write this for an unchecked exception.

This is where Java is fundamentally different. In Java, you can of course add a throws declaration to your methods, even for unchecked exceptions.

from styleguides.

jordao76 avatar jordao76 commented on June 11, 2024

I feel you're still advocating for checked exceptions, although half-baked.

In the situation you just described, there's a plethora of exceptions that can be thrown, and I shouldn't be expected as a client to deal with each one of them, even as precondition checks (in the case of CX_DYNAMIC_CHECK), since there's always the possibility that new exceptions will be added in the future as well. And if I fail to check or catch any one of them, I get a CX_SY_NO_HANDLER wrapping the original exception. Hardly an improvement. In most situations, we want to bubble the exception up to the most high level code running the program, which can catch CX_ROOT, log and respond with an error message to the user.

The solution to me is documenting, as something "stronger, more reliable" is undesirable in most cases and leads us straight into checked exception territory. When that is desirable, then go all the way and use CX_STATIC_CHECK (should be rare).

Look at the corresponding C# method here. C# doesn't have checked exceptions, and that's one of the places where the motivations to the Clean Code recommendation comes from.

How many times have people benefited from the advertised exceptions in a method as CX_DYNAMIC_CHECK? There's no design time check to tell you if you're missing any exceptions. How many CX_SY_NO_HANDLER exceptions have you seen in the wild? Note also that this exception is very confusing, many people don't really know what that means.

from styleguides.

HrFlorianHoffmann avatar HrFlorianHoffmann commented on June 11, 2024

Let's explore C#, I am not familiar with it. I assume there is such a thing as libraries in C#? Suppose you get a library with a RestClient class that does REST calls, and that HTTP values other than OK are reported as exceptions.

A common resilience pattern in REST is that you retry requests that failed for reasons such as timeouts, in the hope that the server can be reached some seconds later. How do you know which exception the class throws in the timeout case to know what to catch and react to? Is it the API documentation? The unit tests?

from styleguides.

jordao76 avatar jordao76 commented on June 11, 2024

That kind of thing is present in the documentation of such methods in C#. The API doesn't force the client to catch anything. If you want to implement a resilience pattern, like a retry or a circuit-breaker, you can catch it. The unit tests should be part of your client code, you shouldn't need to have access to the API code. You can simulate failure operations with mocks.

I can see the argument for checked exceptions in this kind of API (like CX_STATIC_CHECK), but I don't see the argument for CX_DYNAMIC_CHECK, which would be wrapped in a CX_SY_NO_HANDLER if not handled/forwarded in the immediately calling code. This to me is too surprising and a potential source of frustration, since CX_SY_NO_HANDLER is an implicit exception raised by the ABAP infrastructure which wraps the real exception. It's telling you something is wrong with the code calling the API, diverting attention from the real problem, which could potentially be solved far from the calling code (e.g. with UI validation).

However, most ABAP code that we create as application developers is business application code. Very rarely this kind of infrastructure APIs (file open, REST). Business exceptions are mostly validation errors, invalid state of a business object, or similar issues, and I rarely see the need for checked exceptions in this context. Even validations errors I would prefer not to use exceptions, just populate a message container.

Mostly CX_NO_CHECK. Rarely CX_STATIC_CHECK. Never CX_DYNAMIC_CHECK.

When telling Java developers to "use unchecked exceptions", I'm not sure that Uncle Bob is advocating to put the unchecked exceptions in the method signature. In Java you can do this, in C# you can't.

Interestingly though, I tried it last night, and ABAP didn't complain when I annotated my method with CX_NO_CHECK exceptions (in the RAISING clause), even though the documentation says it would.

I know I'm going against what even the ABAP documentation says about these exceptions. Perhaps my take is not the right one for this guide. I only have myself to blame, since I worked many years with C# and Java, and I always tended to favor C#'s style.

from styleguides.

HrFlorianHoffmann avatar HrFlorianHoffmann commented on June 11, 2024

Let's first focus on the question whether unchecked or checked should be the default.

Unchecked exceptions decouple the code and make refactoring easier. In turn, they increase unreliability.

Let's say method read_file throws the cx_no_check exception cx_file_not_found. A consumer catches that exception and reacts to it in some meaningful way. Now the developers of read_file change the method and throw the other unchecked exception cx_unknown_file instead.

There is no reliable way how the provider could inform the consumer that the signature changed. Of course they could write ABAP doc, send out change logs, or do usage lookup and write e-mails to all consumers. In practice, ABAP doc is not used widely, we don't keep change logs for ABAP, usage checks miss other systems, and people get so many e-mails they regularly miss important ones. We must assume that the provider's info won't reach all consumers.

The consumer also has trouble to reliably identify the signature change. His unit tests are no help because they will still throw the now decomissioned cx_file_not_found he mocked earlier. The method's definition - in the improbable event he should look at it again in some code review - is still the same and doesn't reveal the change. Static code checks and coverage calculation don't explore the transitive hull of all possible exceptions, so won't reveal that his CATCH clause is now mismatched. The IDE doesn't indicate what exceptions might come out of a method.

The only safeguard the consumer could install are higher level component or system tests that test the two pieces of production code together. However, these tests are slow, expensive to build/maintain, and have higher turnaround time (nightly build, not part of Ctrl+Shift+F10 runs). As a consequence, we'd like to minimize their number, but now find we have to increasingly use them in all places where we have no full control over all involved parts.

In summary, unchecked exceptions seem to work well in constellations where you do not care about exceptions at all, and all of them bubble upwards to a general catch clause at the very top. In combinations where catches are needed though, they introduce a dangerous element of instability. The Compromises section tries to relate that.

My impression is also that tools like the ABAP Development Tools, the Code Inspector, and the Coverage Analyzer would need to identify breaking CATCH clauses better to make them safer to use.

from styleguides.

jordao76 avatar jordao76 commented on June 11, 2024

Oh somehow I missed that page you linked! I think that almost captures the most common pattern. I would change it so that upper_method catches CX_ROOT, or a suitable super class of all your application exceptions. I think upper_method represents a high level method implementing a use case, orchestrating many middle method calls. In my view, CX_NO_CHECK is still the best to use. Uncle Bob tells us to use unchecked exceptions, but again I don't think he advises us to declare them in lower_method.

Your file read example can use CX_STATIC_CHECK, but one could still use CX_NO_CHECK. The most common way to deal with that exception (file not found) to me would be again to catch CX_ROOT at the highest level, log and dump (if in background) or log and show an error message to the user (if interactive). You can definitely validate if the file exists and provide a more specific error message, but I still wouldn't go for CX_DYNAMIC_CHECK (because I'd prefer to avoid CX_SY_NO_HANDLER at all). The exception error message text should clearly tell the user what's wrong. With CX_STATIC_CHECK I would have to bubble up the exception, or catch it and wrap it in a CX_NO_CHECK, creating arguably unwanted ceremony in the middle layer.

Also, declaring the exception as CX_DYNAMIC_CHECK does NOT (AFAIK) give us any warnings in the IDE or syntax checks. So your example of changing from cx_file_not_found to cx_unknown_file wouldn't work with that superclass.

I had the following thought the other day: usually when you hear about checked exceptions, the rule is like follows: "use checked exceptions if a client can reasonably be expected to recover from the exception". You also have the rule to "not use exceptions to control the normal flow of your application". I think both rules kind of contradict each other.

What would you reasonably do if a file not found exception is thrown? Do you search for the file somewhere else? If that's the case, that would be application logic that should not be in a catch block.

from styleguides.

jordao76 avatar jordao76 commented on June 11, 2024

...and again, you mention that with cx_no_check, declaring the exception in lower_method would fail with a syntax error, and indeed that's what the documentation kinda tells us, although not with those specific words. Curiously enough, I was able to declare cx_no_check in a method and I had no syntax errors, no ATCs, nada. Is this an unimplemented check?

from styleguides.

fabianlupa avatar fabianlupa commented on June 11, 2024

...and again, you mention that with cx_no_check, declaring the exception in lower_method would fail with a syntax error, and indeed that's what the documentation kinda tells us, although not with those specific words. Curiously enough, I was able to declare cx_no_check in a method and I had no syntax errors, no ATCs, nada. Is this an unimplemented check?

This results in a syntax error for me ("CX_NO_CHECK inherits neither from CX_DYNAMIC_CHECK nor CX_STATIC_CHECK"), both in global and local classes.

from styleguides.

jordao76 avatar jordao76 commented on June 11, 2024

I'm glad you could verify that, @flaiker. In my system it worked differently.... go figure.

from styleguides.

jordao76 avatar jordao76 commented on June 11, 2024

@flaiker , just to add to my investigation, I did test a global class and a local test class. Here is the local test class, which passed with flying colors:

CLASS my_static_exception DEFINITION INHERITING FROM cx_static_check.
ENDCLASS.
CLASS my_dynamic_exception DEFINITION INHERITING FROM cx_dynamic_check.
ENDCLASS.
CLASS my_runtime_exception DEFINITION INHERITING FROM cx_no_check.
ENDCLASS.

CLASS exc_test DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
  METHODS:
    raising_static RAISING my_static_exception,
    raising_dynamic_decl RAISING my_dynamic_exception,
    raising_dynamic_no_decl,
    raising_runtime_no_decl,
    raising_runtime_decl RAISING my_runtime_exception,
    raising_runtime_decl_no_check RAISING cx_no_check,
    exceptions_test FOR TESTING.
ENDCLASS.

CLASS exc_test IMPLEMENTATION.

  METHOD exceptions_test.
    DATA(raise_count) = 0.

    TRY.
        raising_static( ).
    CATCH my_static_exception.
        raise_count += 1.
    ENDTRY.

    TRY.
        raising_dynamic_decl( ).
    CATCH my_dynamic_exception.
        raise_count += 1.
    ENDTRY.

    TRY.
        raising_dynamic_no_decl( ).
    CATCH cx_sy_no_handler.
        raise_count += 1.
    ENDTRY.

    TRY.
        raising_runtime_no_decl( ).
    CATCH my_runtime_exception.
        raise_count += 1.
    ENDTRY.

    TRY.
        raising_runtime_decl( ).
    CATCH my_runtime_exception.
        raise_count += 1.
    ENDTRY.

    TRY.
        raising_runtime_decl_no_check( ).
    CATCH my_runtime_exception.
        raise_count += 1.
    ENDTRY.

    cl_abap_unit_assert=>assert_equals( msg = 'Wrong number of exceptions was raised' exp = 6 act = raise_count ).
  ENDMETHOD.

  METHOD raising_dynamic_decl.
    RAISE EXCEPTION TYPE my_dynamic_exception.
  ENDMETHOD.

  METHOD raising_dynamic_no_decl.
    RAISE EXCEPTION TYPE my_dynamic_exception.
  ENDMETHOD.

  METHOD raising_runtime_no_decl.
    RAISE EXCEPTION TYPE my_runtime_exception.
  ENDMETHOD.

  METHOD raising_runtime_decl.
    RAISE EXCEPTION TYPE my_runtime_exception.
  ENDMETHOD.

  METHOD raising_runtime_decl_no_check.
    RAISE EXCEPTION TYPE my_runtime_exception.
  ENDMETHOD.

  METHOD raising_static.
    RAISE EXCEPTION TYPE my_static_exception.
  ENDMETHOD.

ENDCLASS.

from styleguides.

fabianlupa avatar fabianlupa commented on June 11, 2024

I get the syntax error (7.40SP20).
image

Looking at your += syntax I assume you are on 7.54? I'd guess then it's either a regression or a design change that's not published at all?

from styleguides.

jordao76 avatar jordao76 commented on June 11, 2024

No idea. Either way we should stick to the documented behavior, which is the one you're experiencing. Thanks for checking that.

from styleguides.

fabianlupa avatar fabianlupa commented on June 11, 2024

Confirmed this with the ABAP language group. In response to repeated feedback, including our prior discussion of this issue, they added the possibility to declare cx_no_check exceptions in raising clauses. This is available from AS ABAP 7.78/7.55 on. The documentation is behind schedule, so this new feature is not documented, yet.

Amazing! This wil probably cause me to change most of my cx_dynamic_check exceptions to cx_no_check (they were only dynamic, to be able to document them in the method signature and not force the caller to catch them).

This unfortunately leaves this styleguide in a weird situation. It would now be quite easy to recommend using cx_no_check, but basically no one has the required AS ABAP release and will have for years to come. I doubt this gets backported to earlier releases?

from styleguides.

fabianlupa avatar fabianlupa commented on June 11, 2024

I still would recommend using cx_no_check. Just document the exceptions with ABAP doc. There's no need to declare them in the raising clause.

In my opinion that comes with high cost:

  • ABAP Doc is great, but it will only be seen by users of ADT and hardworking SE24 users that don't use the form based editor and manually look at the method definition.
  • There's no auto generation for catch blocks.
  • There's no auto generation for the ABAP Doc documentation of the exception.
  • You cannot use the intended @raising function of ABAP Doc, because the quick fix to remove documentation for non-existing signature parts will remove it.
  • There's no static analysis to find the exception in the signature, therefore the refactoring tools (i. e. renaming the exception class) will not catch it to also refactor the documentation.
  • If you do also use static_check exceptions the documentation is weirdly mixed (part of the exceptions are documented in the body-part and the others in the parameter-part).

Currently I'd rather have my correctly documented and declared dynamic_check exceptions in the method signature (and live with them being wrapped into cx_sy_no_handler in some cases) than to have the drawbacks listed above.

from styleguides.

jordao76 avatar jordao76 commented on June 11, 2024

Thanks for those points. I certainly don't have that much experience with ABAP Doc. My general comment was about documenting the exception, regardless if it would be in ABAP Doc or some other form. Any consumer of your classes or APIs should clearly have a place to learn about it before using it.

from styleguides.

niuniuch avatar niuniuch commented on June 11, 2024

The post by HrFlorianHoffmann advocating use of checked exceptions as default is a bit misguided because the provided example is actually one of the rare cases where a checked exception makes perfect sense and I would consider using one myself.

If what you're mostly working on are small code modules/libraries to be used by other teams then it might feel like a general rule. Such small libraries pretty much don't have anything but a public API, so the use of checked exceptions is in order.

However, I'm mostly working on mid to large systems with at least a few hundred classes and often a few dosen calls on the call stack during runtime. Use of checked exceptions anywhere else but the thin public API layer is pure nonsense.
Personally, for me as the system architect, it's very frustrating when a new team member comes in and starts breaking lines of abstraction by adding raising clauses propagated upwards from the bottom layers, because Clean ABAP said so.

When working on large systems it's essential to manage complexity by isolating higher level classes from the implementation details of the lower level classes. Checked exceptions break that rule, which is very very VERY bad.

from styleguides.

niuniuch avatar niuniuch commented on June 11, 2024

I'd be cautious with the raising section.
I'm fine with declaring exceptions, as long as it's just a list of RAISE clauses from the method itself. If you start declaring exceptions that might get propagated from nested method calls then it's even worse than using checked exceptions in the first place - you get all the downsides of checked exceptions without the associated benefits.

100% in favour of a single exception hierarchy for internal exceptions with 1 ZCX superclass inheriting from CX_NO_CHECK.

from styleguides.

fabianlupa avatar fabianlupa commented on June 11, 2024

So practically speaking you do this with the internal / external approach?

  • CX_ROOT
    • CX_NO_CHECK
      • ZCX_ABC_NO_CHECK
        • ZCX_ABC_NO_AUTHORITY
    • CX_STATIC_CHECK
      • ZCX_ABC_STATIC_CHECK
        • ZCX_ABC_NO_AUTHORITY_EXT

to be able to use no check internally and static check externally? And then TRY CATCH reraise at the API layer??? Surely not.

Or do you try catch reraise every ZCX_ABC_NO_CHECK at the API layer but only have one ZCX_ABC_API_ERROR static check exception which then points to the concrete instance of ZCX_ABC_NO_CHECK via previous? Causing the API consumer to not be able to differentiate between error cases unless relying on the previous attribute whose values are unknown.

from styleguides.

niuniuch avatar niuniuch commented on June 11, 2024

What the API consumer needs to know is that something went wrong and perhaps an error message to display to the user. The consumer doesn't need or want to know what excactly the error condision is. That's the whole purpose of breaking a large system into subsystems - to hide implementation details of one part from the other parts.

In practice I usually catch CX_ROOT in the API layer and raise a checked ZCX_ABC_API_ERROR, or perhaps one of a small set of checked exceptions if really necessary (i.e. internal system error vs invalid input).
You don't pass the unchecked exception as previous - in order to make sense of it, the consumer would need to know implementation details which violates the line of abstraction.

Remember that following Clean Code doesn't bring value on it's own - the book just goes into detail on some of the concepts discussed in other books, like Agile Software Development and Clean Architecture. If you're designing your systems in a way recommended by Robert Martin (and many other prominent software engineers like Martin Fowler, Kent Beck, Dave Farley, Allen Holub etc.) then Clean Code is a cherry on top.
If you're not doing that, then you might as well use checked exceptions and functional groups disguised as static abstract classes. And in many cases that's perfecly fine! It's only when a system reaches a certain critical mass, it starts collapsing under it's own complexity - unless it was designed from the start with complexity management in mind.

Of course the problem is how to know at the start if the system will need complexity management or not? Unless you have a magic crystal ball I recommend starting every project assuming it will need it at some point. With this approach, the worst thing that can happen is that you will end up with a little over-engineering. The consequences of erring on the other side can be much more severe.

from styleguides.

fabianlupa avatar fabianlupa commented on June 11, 2024

The consumer doesn't need or want to know what excactly the error condision is.

Hmm, I would have said the consumer does want to know at least somewhat to be able to react differently. Propagate an insufficient authorization error up and just log it or retry a network connectivity issue a few times. But I guess that kind of handling should already have happenend behind the API facade so the caller doesn't actually need to know, as for example the network connectivity would be an implementation detail.

You don't pass the unchecked exception as previous - in order to make sense of it, the consumer would need to know implementation details which violates the line of abstraction.

Regarding this: I do pass them not for the consumer to make sense of them but for the runtime to be able to log the whole exception stack from beginning to end (uncaught exception / RAISE SHORTDUMP / some kind of logging component).

In practice I usually catch CX_ROOT in the API layer and raise a checked ZCX_ABC_API_ERROR

I would disagree with that. By catching CX_ROOT you also catch all CX_SY* exceptions including things like database deadlocks that are extemely painful to analyze if there is no shortdump for the exception. Which catching CX_ROOT will do, unless you have your own logging component in the catch block so you do not need to rely on ST22. Catching ZCX_ABC_NO_CHECK seems reasonable to me though.

On the other hand, how do you handle the static check errors on the API consumer side? You don't want to directly use them as they'd force you to declare and propagate as well since they are checked. Do you wrap those there inside of CX_NO_CHECK exceptions again until another API facade is reached?

from styleguides.

niuniuch avatar niuniuch commented on June 11, 2024

Hmm, I would have said the consumer does want to know at least somewhat to be able to react differently. Propagate an insufficient authorization error up and just log it or retry a network connectivity issue a few times. But I guess that kind of handling should already have happenend behind the API facade so the caller doesn't actually need to know, as for example the network connectivity would be an implementation detail.

Excaclty. I would say that if the API consumer needs to know it's a connectivity issue so it can retry then it's a architectural flaw and the line of abstraction needs to be in a different place.

Regarding this: I do pass them not for the consumer to make sense of them but for the runtime to be able to log the whole exception stack from beginning to end (uncaught exception / RAISE SHORTDUMP / some kind of logging component).
I would disagree with that. By catching CX_ROOT you also catch all CX_SY* exceptions including things like database deadlocks that are extemely painful to analyze if there is no shortdump for the exception. Which catching CX_ROOT will do, unless you have your own logging component in the catch block so you do not need to rely on ST22. Catching ZCX_ABC_NO_CHECK seems reasonable to me though.

I'm not going to disagree with that, but dumps are a tricky subject. For many years I was a strong advocate for dumping, because of the reasons you mention. But back then I was working as an (almost) internal developer. Now I work in a environment where external clients use the systems I'm working on so dumping is a big no-no because it hurts the company's image - you always want to end the execution with some kind of 'Service is unavailable, please raise a ticket' message.
I actually searched for a way to generate a short dump without really dumping, but I couldn't find how to do it. Is it possible?

from styleguides.

fabianlupa avatar fabianlupa commented on June 11, 2024

I actually searched for a way to generate a short dump without really dumping, but I couldn't find how to do it. Is it possible?

I don't think so. The only thing I can think of is isolating a process using RFC, then the shortdump will be created but the parent can still continue execution (abapGit's integration test suite uses this technique and ABAP Unit as well I think). For creating trace data directly inside a catch block various applications created their own logging and tracing tools to serialize environment data and present it in some kind of analysis program (/IWFND/ERROR_TRACE for example).

from styleguides.

niuniuch avatar niuniuch commented on June 11, 2024

Maybe let's start with simple things. Can we all agree that CX_DYNAMIC_CHECK is an oddity unknown in more civilised languages and it's always better to just use CX_NO_CHECK?

To me it looks like the designers of ABAP OO realised that using checked exceptions is not feasible in more complex developments, but didn't have the courage to do the right thing, because ABAP OO was clearly based on an early version of Java, and back then the Java world still thought that checked exceptions are a good idea....

from styleguides.

fabianlupa avatar fabianlupa commented on June 11, 2024

Maybe let's start with simple things. Can we all agree that CX_DYNAMIC_CHECK is an oddity unknown in more civilised languages and it's always better to just use CX_NO_CHECK?

I agree on 7.55 and up, where CX_NO_CHECK exceptions can be declared in method signatures. Before that CX_DYNAMIC_CHECK allowed for documenting exceptions in method signatures without forcing the caller to catch them (at the cost that higher levels of the call stack cannot catch them because of CX_SY_NO_HANDLER), which often was a fair compromise for me. As discussed above.

from styleguides.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.