aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChloe Kudryavtsev <code@toast.bunkerlabs.net>2023-03-22 11:32:26 -0400
committerChloe Kudryavtsev <code@toast.bunkerlabs.net>2023-03-22 11:32:26 -0400
commit449da049509e6ea300ba1c78d5bf0f22a660d306 (patch)
tree559f0208725e4098c29ceb4bbc8f8df66565411a
parentnative: add error elaboration (diff)
native: return rich errors
also provide an error boxer / enricher ala elixir
-rw-r--r--jurl.c36
-rw-r--r--jurl.h1
-rw-r--r--jurl_errors.c2
-rw-r--r--jurl_setopt.c40
-rw-r--r--main.c15
5 files changed, 66 insertions, 28 deletions
diff --git a/jurl.c b/jurl.c
index 9dde785..d1a937b 100644
--- a/jurl.c
+++ b/jurl.c
@@ -30,14 +30,31 @@ jurl_handle *janet_getjurl(Janet *argv, int32_t n) {
return (jurl_handle*)janet_getabstract(argv, n, &jurl_type);
}
+// this function plays fast and loose and I hope the gc doesn't kill me for it
+// anyway, it goes like so:
+// (wrap-error :ok something) -> [:ok something]
+// (wrap-error :err something) -> [:err "explanation of :err"]
+JANET_CFUN(jurl_wrap_error) {
+ janet_fixarity(argc, 2);
+ CURLcode code;
+ if (janet_checktype(argv[0], JANET_NUMBER)) {
+ argv[0] = jurl_geterror(janet_getinteger(argv, 0));
+ }
+ if (!janet_checktype(argv[0], JANET_KEYWORD)) {
+ janet_panicf("jurl_wrap_error: expected number or keyword, got %T", janet_type(argv[0]));
+ }
+ if (!janet_keyeq(argv[0], "ok")) {
+ // will this break one day?
+ // find out next time!
+ argv[1] = jurl_strerror(1, argv);
+ }
+ return janet_wrap_tuple(janet_tuple_n(argv, 2));
+}
+
JANET_CFUN(jurl_new) {
janet_fixarity(argc, 0);
jurl_handle *jurl = (jurl_handle*)janet_abstract(&jurl_type, sizeof(jurl));
jurl->handle = curl_easy_init();
-
- // EXAMPLE
- curl_easy_setopt(jurl->handle, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
-
return janet_wrap_abstract(jurl);
}
@@ -92,7 +109,7 @@ JANET_CFUN(jurl_global_init) {
}
}
global_init_ret:
- return janet_wrap_integer(curl_global_init(flags));
+ return jurl_geterror(curl_global_init(flags));
}
JANET_CFUN(jurl_global_cleanup) {
@@ -100,15 +117,8 @@ JANET_CFUN(jurl_global_cleanup) {
return janet_wrap_nil();
}
-size_t write_buffer_callback(void *contents, size_t size, size_t nmemb, void* userp) {
- size_t realsize = size * nmemb;
- janet_buffer_push_bytes(userp, contents, realsize);
- return realsize;
-}
-
JANET_CFUN(jurl_perform) {
janet_fixarity(argc, 1);
jurl_handle *jurl = (jurl_handle*)janet_getjurl(argv, 0);
- CURLcode res = curl_easy_perform(jurl->handle);
- return janet_wrap_boolean(res == CURLE_OK);
+ return jurl_geterror(curl_easy_perform(jurl->handle));
}
diff --git a/jurl.h b/jurl.h
index fd50466..5b15deb 100644
--- a/jurl.h
+++ b/jurl.h
@@ -26,6 +26,7 @@ JANET_CFUN(jurl_new);
JANET_CFUN(jurl_reset);
JANET_CFUN(jurl_dup);
JANET_CFUN(jurl_perform);
+JANET_CFUN(jurl_wrap_error);
jurl_handle *janet_getjurl(Janet *argv, int32_t n);
// jurl_callbacks.c
diff --git a/jurl_errors.c b/jurl_errors.c
index c2bbd0f..94219fe 100644
--- a/jurl_errors.c
+++ b/jurl_errors.c
@@ -133,7 +133,7 @@ JANET_CFUN(jurl_strerror) {
}
break;
case JANET_TFLAG_NUMBER:
- code = janet_getinteger64(argv, 0); // take advantage of the macro check rather than arg
+ code = janet_unwrap_integer(arg);
break;
default:
janet_panicf("expected keyword or number in jurl_strerror, got %T", janet_type(arg));
diff --git a/jurl_setopt.c b/jurl_setopt.c
index f1e5e64..d0cb5d2 100644
--- a/jurl_setopt.c
+++ b/jurl_setopt.c
@@ -323,25 +323,39 @@ JANET_CFUN(jurl_setopt) {
switch (opt->type) {
case JURL_PARAMTYPE_BOOLEAN:
if (janet_checktype(argv[2], JANET_NUMBER)) {
- curl_easy_setopt(jurl->handle, opt->opt, janet_getinteger(argv, 2) == 0 ? 0 : 1);
+ return jurl_geterror(
+ curl_easy_setopt(
+ jurl->handle, opt->opt, janet_getinteger(argv, 2) == 0 ? 0 : 1
+ ));
} else {
- curl_easy_setopt(jurl->handle, opt->opt, janet_truthy(argv[2]) ? 1 : 0);
+ return jurl_geterror(
+ curl_easy_setopt(
+ jurl->handle, opt->opt, janet_truthy(argv[2]) ? 1 : 0
+ ));
}
break;
case JURL_PARAMTYPE_LONG:
case JURL_PARAMTYPE_OFF_T:
- curl_easy_setopt(jurl->handle, opt->opt, janet_getinteger64(argv, 2));
+ return jurl_geterror(
+ curl_easy_setopt(jurl->handle, opt->opt, janet_getinteger64(argv, 2)
+ ));
break;
case JURL_PARAMTYPE_STRING:
// strings may be set to null
if (janet_checktype(argv[2], JANET_NIL)) {
- curl_easy_setopt(jurl->handle, opt->opt, NULL);
+ return jurl_geterror(
+ curl_easy_setopt(jurl->handle, opt->opt, NULL
+ ));
} else {
- curl_easy_setopt(jurl->handle, opt->opt, janet_getcstring(argv, 2));
+ return jurl_geterror(
+ curl_easy_setopt(jurl->handle, opt->opt, janet_getcstring(argv, 2)
+ ));
}
break;
case JURL_PARAMTYPE_FILE:
- curl_easy_setopt(jurl->handle, opt->opt, janet_getjfile(argv, 2));
+ return jurl_geterror(
+ curl_easy_setopt(jurl->handle, opt->opt, janet_getjfile(argv, 2)
+ ));
break;
case JURL_PARAMTYPE_SLIST: {
// we register the cleanup ahead of time, because...
@@ -359,19 +373,25 @@ JANET_CFUN(jurl_setopt) {
}
clean->slist = newlist;
}
- curl_easy_setopt(jurl->handle, opt->opt, clean->slist);
+ return jurl_geterror(
+ curl_easy_setopt(jurl->handle, opt->opt, clean->slist
+ ));
break;
}
case JURL_PARAMTYPE_ENUM:
- jurl_setenum(jurl, opt->opt, argv[2]);
+ return jurl_geterror(
+ jurl_setenum(jurl, opt->opt, argv[2]
+ ));
break;
case JURL_PARAMTYPE_CALLBACK:
// callbacks are complex and need individual handling
- jurl_setcallback(jurl, opt->opt, janet_getfunction(argv, 2));
+ return jurl_geterror(
+ jurl_setcallback(jurl, opt->opt, janet_getfunction(argv, 2)
+ ));
break;
default:
janet_panic("jurl_setopt: unrecognized param type");
}
- return janet_wrap_abstract(jurl);
+ return janet_wrap_nil(); // unreachable
}
diff --git a/main.c b/main.c
index fad38d9..7259193 100644
--- a/main.c
+++ b/main.c
@@ -33,11 +33,17 @@ JANET_FN(jurl_perform,
"(jurl-native/perform handle)",
"Perform the request associated with a handle");
+JANET_FN(jurl_wrap_error,
+ "(jurl-native/wrap-error :ok body)"
+ "\n"
+ "(jurl-native/wrap-error :err _)",
+ "Boxes an :ok signal with a body, else the error with its explanation in string form");
+
// jurl_errors.c
-JANET_FN(jurl_geterror,
- "(jurl-native/geterror :error/write-error)"
+JANET_FN(jurl_strerror,
+ "(jurl-native/strerror :error/write-error)"
"\n"
- "(jurl-native/geterror 1234)",
+ "(jurl-native/strerror 1234)",
"Get an explanation string about a jurl error");
// jurl_getinfo.c
@@ -62,9 +68,10 @@ static const JanetRegExt cfuns[] = {
JANET_REG("global-init", jurl_global_init),
JANET_REG("global-cleanup", jurl_global_cleanup),
JANET_REG("perform", jurl_perform),
+ JANET_REG("wrap-error", jurl_wrap_error),
// jurl_errors.c
- JANET_REG("geterror", jurl_geterror),
+ JANET_REG("strerror", jurl_strerror),
// jurl_getinfo.c
JANET_REG("getinfo", jurl_getinfo),