Skip to content

Conversation

@StephanEwen
Copy link
Contributor

This pull request adds two exception base classes: FlinkException and FlinkRuntimeException.
They are useful in improving the way certain parts of the code handle exceptions.

  • FlinkException is a base class for checked exceptions that indicate that something related to using Flink went wrong. It is helpful, because letting a method throw FlinkException rather than Exception already helps to not include all of Java's runtime exceptions, which indicate programming errors, rather than situations that should be recovered.
  • FlinkRuntimeException as a Flink-specific subclass of RuntimeException comes in handy in places where no exceptions were declared, for example when reusing an interface that does not declare exceptions.

Important: This does not mean we should just declare FlinkException everywhere and throw and catch FlinkException and FlinkRuntimeException arbitrarily. Exception handling remains a careful and conscious task.

This also adds the DynamicCodeLoadingException subclass of FlinkException as an example.

* Class.forName(classname).asSubclass(TheType.class).newInstance();
* }
* catch (ClassNotFoundException | ClassCastException | InstantiationException | IllegalAccessException e) {
* throw new DynamicCodeLoadingException(e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no constructor that matches this line of the javadoc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, will fix this

* @param message The exception message
* @param cause The exception that caused this exception
*/
public DynamicCodeLoadingException(String message, Throwable cause) {
Copy link
Contributor

@zentol zentol Feb 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to make this constructor more explicit in the type of exceptions it accepts? (i.e. one constructor each for the exceptions that are typically thrown in situations that we want to cover)

It's probably just bloat, but maybe it would prevent misuse of this exception.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There may be other cases for this exception that we do not anticipate, like for shipping of generated code in bytes that is dynamically converted to classes (not sure what exceptions that will entail, but probably ClassFormatError and so on).

/**
* Creates a new exception with a null message and null cause.
*/
public FlinkRuntimeException() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reasonable use-case for an exception without an error message or cause?

@zentol
Copy link
Contributor

zentol commented Feb 20, 2017

Could you name 1 or 2 examples for situations where you think it is appropriate to throw a FlinkException? Would invalid arguments (like a String being null) be a reason to do so?

@StephanEwen
Copy link
Contributor Author

@zentol There are many places in the runtime that declare throws Exception, for example virtually all of the state handling code. This always came from the desire to throw IOException plus something that expresses that non-I/O stuff related to Flink went wrong. The result was a throws Exception, which also means that you have to catch Exception which you often don't want (because this included RuntimeException and you typically want runtime exception to bubble up a bit further, since they denote bugs by encouraged design).

The only place where throws Exception really makes sense to me is for MapFunction and the likes, to allow them to propagate any type of exception and let recovery handle them.

@StephanEwen
Copy link
Contributor Author

It is arguable whether exceptions should ever have a constructor without a message, I simply did that here for convenience. I have no strong feelings about removing the zero argument constructors.

StephanEwen added a commit to StephanEwen/flink that referenced this pull request Feb 20, 2017
@StephanEwen
Copy link
Contributor Author

Any reservations against merging this after addressing the comments above?

@aljoscha
Copy link
Contributor

This looks good, but what is the reason behind the empty constructors that create an exception without message or cause?

@uce
Copy link
Contributor

uce commented Feb 22, 2017

Hey Stephan! The changes look very good. Thanks also for your explanations, I think this is something that we should focus on more during code reviews. Actually, a section in the Internals or Contribution docs or Wiki would be helpful.

A question by example:
Curator throws Exception on most operations. Previously, this was simply forwarded. Should this now be wrapped in a FlinkRuntimeException?

@tillrohrmann
Copy link
Contributor

Big +1 from my side. I think that more specific exceptions helps to make people think more about the cause of an exception and, thus, also how it should be handled. Especially the fact that we always catch RuntimeException when having throws Exception in the method definition annoyed me a lot.

@uce I think we should not per se wrap all current Exceptions into a FlinkRuntimeException. Better to do a case distinction here.

@StephanEwen
Copy link
Contributor Author

Thanks for the comments. Will address the issues and remove the "no message, no cause" constructors. We should not encourage exceptions without information.

StephanEwen added a commit to StephanEwen/flink that referenced this pull request Feb 23, 2017
@asfgit asfgit closed this in 813c258 Feb 24, 2017
p16i pushed a commit to p16i/flink that referenced this pull request Apr 16, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants