about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--README.md5
-rw-r--r--docs/api.md24
-rw-r--r--include/uv_link_t.h7
-rw-r--r--src/defaults.c8
-rw-r--r--test/src/test-list.h1
-rw-r--r--test/src/test-strerror.c35
-rw-r--r--test/test.gyp1
7 files changed, 76 insertions, 5 deletions
diff --git a/README.md b/README.md
index 31952b9..a8287c6 100644
--- a/README.md
+++ b/README.md
@@ -80,11 +80,6 @@ static int shutdown_impl(uv_link_t* link,
 [API Docs][2]
 [Implementation Guide][3]
 
-## Further Work
-
-* Error reporting. Right now all we get is a UV_... error, it would be nice to
-  have a method for obtaining string description.
-
 ## LICENSE
 
 This software is licensed under the MIT License.
diff --git a/docs/api.md b/docs/api.md
index 2d2877b..b73a428 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -118,6 +118,16 @@ Invoke `shutdown` from the link's [`uv_link_methods_t`][]. Acts similarly to
 `uv_shutdown()`. `cb(uv_link_t* link, int status, void* arg)` is invoked on
 completion.
 
+### const char* uv_link_strerror(...)
+
+* `uv_link_t* link`
+* `int err` - error code, previously either returned the one of the
+  `uv_link...` methods or passed as a negative `nread` to `link->read_cb`
+
+Invoke `strerror` from the link's [`uv_link_methods_t`][]. Acts similarly to
+`uv_strerror()`. Returns a description of error code that has just been given
+back to the user.
+
 ### void uv_link_propagate_alloc_cb(...)
 
 Should be used only by [`uv_link_methods_t`][] implementation.
@@ -385,6 +395,19 @@ is passed only only for internal operation.
 
 *NOTE: semantics are the same as of `uv_close`.*
 
+### .strerror
+
+```c
+const char* (*strerror)(uv_link_t* link, int err);
+```
+
+Invoked by [`uv_link_strerror()`][].
+
+Should return a description string of the `err`, or propagate call to the
+`link->parent` if the error wasn't emitted by the current `link`.
+
+*NOTE: semantics are the same as of `uv_strerror`.*
+
 ### .alloc_cb_override
 
 A method used to override that value of [`uv_link_t.alloc_cb`][] by
@@ -468,6 +491,7 @@ Invoked by `uv_link_propagate_read_cb`. MUST not manage the data in `buf`.
 
 [`uv_link_chain()`]: #int-uv_link_chain
 [`uv_link_close()`]: #void-uv_link_close
+[`uv_link_strerror()`]: #const-char-uv_link_strerror
 [`uv_link_init()`]: #int-uv_link_init
 [`uv_link_methods_t`]: #uv_link_methods_t
 [`uv_link_observer_t.observer_read_cb`]: #observer_read_cb
diff --git a/include/uv_link_t.h b/include/uv_link_t.h
index 61d4cf0..9ba96ad 100644
--- a/include/uv_link_t.h
+++ b/include/uv_link_t.h
@@ -40,6 +40,8 @@ struct uv_link_methods_s {
 
   void (*close)(uv_link_t* link, uv_link_t* source, uv_link_close_cb cb);
 
+  const char* (*strerror)(uv_link_t* link, int err);
+
   /* Overriding callbacks */
   uv_link_alloc_cb alloc_cb_override;
   uv_link_read_cb read_cb_override;
@@ -120,6 +122,10 @@ static int uv_link_shutdown(uv_link_t* link, uv_link_shutdown_cb cb,
   return uv_link_propagate_shutdown(link, link, cb, arg);
 }
 
+static const char* uv_link_strerror(uv_link_t* link, int err) {
+  return link->methods->strerror(link, err);
+}
+
 /* Link Source */
 
 struct uv_link_source_s {
@@ -170,6 +176,7 @@ int uv_link_default_shutdown(uv_link_t* link,
                              void* arg);
 void uv_link_default_close(uv_link_t* link, uv_link_t* source,
                            uv_link_close_cb cb);
+const char* uv_link_default_strerror(uv_link_t* link, int err);
 
 void uv_link_default_alloc_cb_override(uv_link_t* link,
                                        size_t suggested_size,
diff --git a/src/defaults.c b/src/defaults.c
index 1c486f8..a88c80d 100644
--- a/src/defaults.c
+++ b/src/defaults.c
@@ -43,6 +43,14 @@ void uv_link_default_close(uv_link_t* link, uv_link_t* source,
 }
 
 
+const char* uv_link_default_strerror(uv_link_t* link, int err) {
+  if (link->parent == NULL)
+    return uv_strerror(err);
+  else
+    return uv_link_strerror(link->parent, err);
+}
+
+
 void uv_link_default_alloc_cb_override(uv_link_t* link,
                                        size_t suggested_size,
                                        uv_buf_t* buf) {
diff --git a/test/src/test-list.h b/test/src/test-list.h
index 591b858..abb7cda 100644
--- a/test/src/test-list.h
+++ b/test/src/test-list.h
@@ -6,6 +6,7 @@
     V(uv_link_observer_t)                                                     \
     V(close_depth)                                                            \
     V(stop_read_on_error)                                                     \
+    V(strerror)                                                               \
 
 #define TEST_DECL(N) void test__##N();
 
diff --git a/test/src/test-strerror.c b/test/src/test-strerror.c
new file mode 100644
index 0000000..c3b44c2
--- /dev/null
+++ b/test/src/test-strerror.c
@@ -0,0 +1,35 @@
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "test-common.h"
+
+static uv_link_t st_link;
+
+static int close_cb_called;
+
+
+const char* test_strerror(uv_link_t* l, int err) {
+  CHECK_EQ(l, &st_link, "link == st_link");
+  return "Description";
+}
+
+
+static uv_link_methods_t methods = {
+  .strerror = test_strerror,
+  .close = uv_link_default_close
+};
+
+static void close_cb(uv_link_t* l) {
+  close_cb_called++;
+}
+
+
+TEST_IMPL(strerror) {
+  CHECK_EQ(uv_link_init(&st_link, &methods), 0, "uv_link_init()");
+
+  CHECK_EQ(strcmp(uv_link_strerror(&st_link, -1), "Description"), 0,
+           "error description should match");
+
+  uv_link_close(&st_link, close_cb);
+  CHECK_EQ(close_cb_called, 1, "close_cb must be called");
+}
diff --git a/test/test.gyp b/test/test.gyp
index 0bd930d..131b93a 100644
--- a/test/test.gyp
+++ b/test/test.gyp
@@ -18,6 +18,7 @@
       "src/test-uv-link-observer-t.c",
       "src/test-defaults.c",
       "src/test-close.c",
+      "src/test-strerror.c",
     ],
   }],
 }