diff options
| author | 2023-03-22 11:32:26 -0400 | |
|---|---|---|
| committer | 2023-03-22 11:32:26 -0400 | |
| commit | 449da049509e6ea300ba1c78d5bf0f22a660d306 (patch) | |
| tree | 559f0208725e4098c29ceb4bbc8f8df66565411a | |
| parent | native: add error elaboration (diff) | |
native: return rich errors
also provide an error boxer / enricher ala elixir
| -rw-r--r-- | jurl.c | 36 | ||||
| -rw-r--r-- | jurl.h | 1 | ||||
| -rw-r--r-- | jurl_errors.c | 2 | ||||
| -rw-r--r-- | jurl_setopt.c | 40 | ||||
| -rw-r--r-- | main.c | 15 |
5 files changed, 66 insertions, 28 deletions
@@ -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)); } @@ -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 } @@ -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), |
