Skip to content
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions text/0000-network-errors-handling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
- Feature Name: network errors handling
- Start Date: 2017-02-15
- RFC PR: (leave this empty)
- Pony Issue: (leave this empty)

# Summary

Provide API for handling network errors.

# Motivation

Current interfaces, such as `TCPListenNotify`, `TCPConnectionNotify`
and `UDPNotify` do not provide any information about why some action
has failed. This makes it difficult to figure out software
configuration errors. Knowledge about nature of network failure is
essential for production software.

# Detailed design

1. Create a primivite union of possible network errors, similar to
`FileErrNo`, that maps a platform specific errno codes on these
primitive values.

```pony
type SocketErrNo is
( SocketOK
| SocketError
| SocketInUse
| SocketConnRefused
| SocketNetUnreach
| SocketTimeout
)
```

Where:

* `SocketOK' - success
* `SocketInUse` - local address is already in use
* `SocketConnRefused` - no-one listening on the remote address
* `SocketNetUnreach` - no routing to remote host
* `SocketTimeout` - timeout while attempting connection

2. Add private `_errno` field of `SocketErrNo` type into
`TCPConnection`, `UDPSocket` and `TCPListener`. On failure, set
`_errno` using corresponding OS errno code fetched using `SO_ERROR`
socket option

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

On success, we'd also want to set it back to SocketOK, right?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yeah, on any outcome (success or failure) we want to set _errno. I'll fix


3. Create publically available method `errno` which returns `_errno`,
for example:

```pony
fun errno(): SocketErrNo =>
"""
Returns the last error code set for this socket
"""
_errno
```

# How We Teach This

Update the doc strings for `TCPConnectionNotify.connect_failed`,
`UDPNotify.not_listening` and `TCPListenNotify.not_listening`
describing error fetching mechanism described in Design section.

Code example, showing usage of handling errors, is highly encouraged.

# How We Test This

Add test case of making invalid connection, checking that errno is set
uppon call to notifier.

# Drawbacks

Requires changes in `libponyrt/lang/socket.c` since actual value for
`SO_ERROR` is not exposed to pony level.

# Alternatives

Extend notifiers API, so error code is provided uppon call to
notifier. This approach looks not that smooth to integrate as
proposed in Design section.

# Unresolved questions

How proposed API conforms with [RFC 23](https://github.com/ponylang/rfcs/blob/master/text/0023-network-dont-provide-default-implementation-for-failures.md)