Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throws declaration and Checked exception #3074

Closed
Parvinderjit opened this issue May 14, 2023 · 8 comments
Closed

Throws declaration and Checked exception #3074

Parvinderjit opened this issue May 14, 2023 · 8 comments
Labels
feature Proposed language feature that solves one or more problems state-rejected This will not be worked on

Comments

@Parvinderjit
Copy link

Hi Team,

I feel we can improve the exception handling experience by introducing some kind of throws statement. Right now when any method/function needs to throws an exception either we needs to check for the implementation/documentation of that function. What if compiler suggests us the function can throws an exception so we needs to call that method under from try catch statement.

And what if that compiler suggests us the type of exception as well like Java's checked exceptions.

@Parvinderjit Parvinderjit added the feature Proposed language feature that solves one or more problems label May 14, 2023
@Wdestroier
Copy link

An alternative is to return a record with nullable values:

(Socket?, UnknownHostException?, IOException?) open({
  required String host,
  required (String?, int?) port
}) {
  if (_isUnknownHost(host)) return (null, UnknownHostException(), null);
  Socket? socket = _tryOpenSocket(host, port);
  return (socket, null, socket == null ? IOException() : null);
}

final (socket, err1, err2) = open(
  host: 'localhost',
  port: (Platform.environment['PORT'], null),
);

switch (socket) {
  Socket() => _sendPacket(socket),
  _ => _showError((err1 ?? err2)!.message);
}

To improve the readability, I suggest allowing to return untagged union types:

Socket | UnknownHostException | IOException open({
  required String host,
  required String | int port,
}) {
  if (_isUnknownHost(host)) return UnknownHostException();
  return _tryOpenSocket(host, port) ?? IOException();
}

final socket = open(
  host: 'localhost',
  port: Platform.environment['PORT'],
);

switch (socket) {
  Socket() => _sendPacket(socket),
  _ err => _showError(err.message),
};

@mateusfccp
Copy link
Contributor

Duplicate of #984.

@Parvinderjit
Copy link
Author

Yes @Wdestroier it's one of the way. But I think if language support Exception handling there should be way which informs the developers to handle it nicely. Suppose if compiler informs us that method is throwing the error so there will be lesser chance of production error. I mean there should be some kind of warning from compiler that one should wrap the call in the try block.

@Parvinderjit
Copy link
Author

Parvinderjit commented May 15, 2023

I read the thread #984. Let's leave for the checked exceptions. What if we just introduce throws statement which just informs us that the method can throw an exception so we can handle that.

like in swift if method signature has throws keyword then we must have to call the method from do try block.

@Wdestroier
Copy link

The recommended action is to write a dartdoc comment:

/// Throws a [FileSystemException] if the file is locked.
void write(List<int> bytes) {
  // ...
}

Another alternative is to create an annotation:

class Throws {
  final Set<Type> exceptionTypes;

  const Throws([this.exceptionTypes = const <Type>{}]);
}

@Throws({FileSystemException})
void write(List<int> bytes) {
  // ...
}

However, you won't get a warning from the linter or an error from the compiler. See dart-lang/sdk#45884 for more.

I recommend you to check how other modern programming languages such as Kotlin, TypeScript, Go and Rust handle checked exceptions. Hint: no checked exceptions, multiple return values and Result/Ok/Err types.

@lrhn lrhn changed the title Throws Statements and Checked exception Throws declaration and Checked exception May 15, 2023
@lrhn
Copy link
Member

lrhn commented May 15, 2023

Closing this and deferring to #984, which is closed, so that's a "not planned" for checked exceptions in Dart.

@lrhn lrhn closed this as completed May 15, 2023
@lrhn lrhn added the state-rejected This will not be worked on label May 15, 2023
@Parvinderjit
Copy link
Author

What about the throws statement @lrhn ?

@lrhn
Copy link
Member

lrhn commented May 15, 2023

As I remember it, that's also covered in #984.

We have no plan to allow you to declare which types are thrown by a function, if it has no effect in the language at all. Then it's just documentation, and it can just as well be put in documentation.

If it has an effect, like requiring you to call the function in a try-body, then it's covered by #984 as an effect on the function type, which doesn't interact well with first-class functions, or async code for that matter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems state-rejected This will not be worked on
Projects
None yet
Development

No branches or pull requests

4 participants