aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChloe Kudryavtsev <code@toast.bunkerlabs.net>2023-03-22 10:39:04 -0400
committerChloe Kudryavtsev <code@toast.bunkerlabs.net>2023-03-22 10:39:04 -0400
commitca6b2413a55b51082a06d4baecd61fea07fa209d (patch)
tree0510542b5b601a40073fd85d22baa462f4fc8b16
parentnative: remove extern by adding a getjurl fn (diff)
native: add error elaboration
-rw-r--r--jurl.h4
-rw-r--r--jurl_errors.c143
-rw-r--r--main.c10
-rw-r--r--project.janet2
4 files changed, 158 insertions, 1 deletions
diff --git a/jurl.h b/jurl.h
index c398b14..fd50466 100644
--- a/jurl.h
+++ b/jurl.h
@@ -34,6 +34,10 @@ CURLcode jurl_setcallback(jurl_handle *jurl, CURLoption opt, JanetFunction *fun)
// jurl_enums.c
CURLcode jurl_setenum(jurl_handle *jurl, CURLoption opt, Janet val);
+// jurl_errors.c
+Janet jurl_geterror(CURLcode code);
+JANET_CFUN(jurl_strerror);
+
// jurl_getinfo.c
JANET_CFUN(jurl_getopt);
diff --git a/jurl_errors.c b/jurl_errors.c
new file mode 100644
index 0000000..c2bbd0f
--- /dev/null
+++ b/jurl_errors.c
@@ -0,0 +1,143 @@
+#include "jurl.h"
+
+struct jurl_error {
+ CURLcode code;
+ char *keyword;
+};
+static const struct jurl_error jurl_errors[] = {
+ {CURLE_OK, "ok"}, // only unprefixed keyword in the collection
+ {CURLE_UNSUPPORTED_PROTOCOL, "error/unsupported-protocol"},
+ {CURLE_FAILED_INIT, "error/failed-init"},
+ {CURLE_URL_MALFORMAT, "error/url-malformat"},
+ {CURLE_NOT_BUILT_IN, "error/not-built-in"},
+ {CURLE_COULDNT_RESOLVE_PROXY, "error/couldnt-resolve-proxy"},
+ {CURLE_COULDNT_RESOLVE_HOST, "error/couldnt-resolve-host"},
+ {CURLE_COULDNT_CONNECT, "error/couldnt-connect"},
+ {CURLE_WEIRD_SERVER_REPLY, "error/weird-server-reply"},
+ {CURLE_REMOTE_ACCESS_DENIED, "error/remote-access-denied"},
+ {CURLE_FTP_ACCEPT_FAILED, "error/ftp-access-failed"},
+ {CURLE_FTP_WEIRD_PASS_REPLY, "error/ftp-weird-pass-reply"},
+ {CURLE_FTP_ACCEPT_TIMEOUT, "error/ftp-accept-timeout"},
+ {CURLE_FTP_WEIRD_PASV_REPLY, "error/ftp-weird-pasv-reply"},
+ {CURLE_FTP_WEIRD_227_FORMAT, "error/ftp-weird-227-format"},
+ {CURLE_FTP_CANT_GET_HOST, "error/ftp-cant-get-host"},
+ {CURLE_HTTP2, "error/http2"},
+ {CURLE_FTP_COULDNT_SET_TYPE, "error/ftp-couldnt-set-type"},
+ {CURLE_PARTIAL_FILE, "error/partial-file"},
+ {CURLE_FTP_COULDNT_RETR_FILE, "error/ftp-couldnt-retr-file"},
+ // SKIP: 20: obsolete
+ {CURLE_QUOTE_ERROR, "error/quote-error"},
+ {CURLE_HTTP_RETURNED_ERROR, "error/http-returned-error"},
+ {CURLE_WRITE_ERROR, "error/write-error"},
+ // SKIP: 24: obsolete
+ {CURLE_UPLOAD_FAILED, "error/upload-failed"},
+ {CURLE_READ_ERROR, "error/read-error"},
+ {CURLE_OUT_OF_MEMORY, "error/out-of-memory"},
+ {CURLE_OPERATION_TIMEDOUT, "error/operation-timeout"},
+ // SKIP: 29: obsolete
+ {CURLE_FTP_PORT_FAILED, "error/ftp-port-failed"},
+ {CURLE_FTP_COULDNT_USE_REST, "error/ftp-couldnt-use-rest"},
+ // SKIP: 32: obsolete
+ {CURLE_RANGE_ERROR, "error/range-error"},
+ {CURLE_HTTP_POST_ERROR, "error/http-post-error"},
+ {CURLE_SSL_CONNECT_ERROR, "error/ssl-connect-error"},
+ {CURLE_BAD_DOWNLOAD_RESUME, "error/bad-download-resume"},
+ {CURLE_FILE_COULDNT_READ_FILE, "error/file-couldnt-read-file"},
+ {CURLE_LDAP_CANNOT_BIND, "error/ldap-cannot-bind"},
+ {CURLE_LDAP_SEARCH_FAILED, "error/ldap-search-failed"},
+ // SKIP: 40: obsolete
+ {CURLE_FUNCTION_NOT_FOUND, "error/function-not-found"},
+ {CURLE_ABORTED_BY_CALLBACK, "error/aborted-by-callback"},
+ {CURLE_BAD_FUNCTION_ARGUMENT, "error/bad-function-argument"},
+ // SKIP: 44: obsolete
+ {CURLE_INTERFACE_FAILED, "error/interface-failed"},
+ // SKIP: 46: obsolete
+ {CURLE_TOO_MANY_REDIRECTS, "error/too-many-redirects"},
+ {CURLE_UNKNOWN_OPTION, "error/unknown-option"},
+ {CURLE_SETOPT_OPTION_SYNTAX, "error/setopt-option-syntax"},
+ // SKIP: 50: obsolete
+ // SKIP: 51: obsolete
+ {CURLE_GOT_NOTHING, "error/got-nothing"},
+ {CURLE_SSL_ENGINE_NOTFOUND, "error/ssl-engine-notfound"},
+ {CURLE_SSL_ENGINE_SETFAILED, "error/ssl-engine-setfailed"},
+ {CURLE_SEND_ERROR, "error/send-error"},
+ {CURLE_RECV_ERROR, "error/recv-error"},
+ // SKIP: 57: obsolete
+ {CURLE_SSL_CERTPROBLEM, "error/ssl-certproblem"},
+ {CURLE_SSL_CIPHER, "error/ssl-cipher"},
+ {CURLE_PEER_FAILED_VERIFICATION, "error/peer-failed-verification"},
+ {CURLE_BAD_CONTENT_ENCODING, "error/bad-content-encoding"},
+ // SKIP: 62: obsolete
+ {CURLE_FILESIZE_EXCEEDED, "error/filesize-exceeded"},
+ {CURLE_USE_SSL_FAILED, "error/use-ssl-failed"},
+ {CURLE_SEND_FAIL_REWIND, "error/send-fail-rewind"},
+ {CURLE_SSL_ENGINE_INITFAILED, "error/ssl-engine-initfailed"},
+ {CURLE_LOGIN_DENIED, "error/login-denied"},
+ {CURLE_TFTP_NOTFOUND, "error/tftp-notfound"},
+ {CURLE_TFTP_PERM, "error/tftp-perm"},
+ {CURLE_REMOTE_DISK_FULL, "error/remote-disk-full"},
+ {CURLE_TFTP_ILLEGAL, "error/tftp-illegal"},
+ {CURLE_TFTP_UNKNOWNID, "error/tftp-unknownid"},
+ {CURLE_REMOTE_FILE_EXISTS, "error/remote-file-exists"},
+ {CURLE_TFTP_NOSUCHUSER, "error/tftp-nosuchuser"},
+ // SKIP: 75: obsolete
+ // SKIP: 76: obsolete
+ {CURLE_SSL_CACERT_BADFILE, "error/ssl-cacert-badfile"},
+ {CURLE_REMOTE_FILE_NOT_FOUND, "error/remote-file-not-found"},
+ {CURLE_SSH, "error/ssh"},
+ {CURLE_SSL_SHUTDOWN_FAILED, "error/ssl-shutdown-failed"},
+ {CURLE_AGAIN, "error/again"},
+ {CURLE_SSL_CRL_BADFILE, "error/ssl-crl-badfile"},
+ {CURLE_SSL_ISSUER_ERROR, "error/ssl-issuer-error"},
+ {CURLE_FTP_PRET_FAILED, "error/ftp-pret-failed"},
+ {CURLE_RTSP_CSEQ_ERROR, "error/rtsp-cseq-error"},
+ {CURLE_RTSP_SESSION_ERROR, "error/rtsp-session-error"},
+ {CURLE_FTP_BAD_FILE_LIST, "error/ftp-bad-file-list"},
+ {CURLE_CHUNK_FAILED, "error/chunk-failed"},
+ {CURLE_NO_CONNECTION_AVAILABLE, "error/no-connection-available"},
+ {CURLE_SSL_PINNEDPUBKEYNOTMATCH, "error/ssl-pinnedpubkeynotmatch"},
+ {CURLE_SSL_INVALIDCERTSTATUS, "error/ssl-invalidcertstatus"},
+ {CURLE_HTTP2_STREAM, "error/http2-stream"},
+ {CURLE_RECURSIVE_API_CALL, "error/recursive-api-call"},
+ {CURLE_AUTH_ERROR, "error/auth-error"},
+ {CURLE_HTTP3, "error/http3"},
+ {CURLE_QUIC_CONNECT_ERROR, "error/quic-connect-error"},
+ {CURLE_PROXY, "error/proxy"},
+ {CURLE_SSL_CLIENTCERT, "error/ssl-clientcert"},
+ {CURLE_UNRECOVERABLE_POLL, "error/unrecoverable-poll"},
+};
+#define jurl_error_size (sizeof(jurl_errors) / sizeof(struct jurl_error))
+
+// translate a CURLcode return code into a keyword
+Janet jurl_geterror(CURLcode code) {
+ for (size_t i = 0; i < jurl_error_size; i++) {
+ if (jurl_errors[i].code == code) {
+ return janet_ckeywordv(jurl_errors[i].keyword);
+ }
+ }
+ janet_panicf("jurl_geterror: could not find error for code %d", code);
+ return janet_wrap_nil(); // unreachable
+}
+
+JANET_CFUN(jurl_strerror) {
+ janet_fixarity(argc, 1);
+ CURLcode code;
+ Janet arg = argv[0];
+ switch (janet_checktypes(arg, JANET_TFLAG_KEYWORD | JANET_TFLAG_NUMBER)) {
+ case JANET_TFLAG_KEYWORD:
+ for (size_t i = 0; i < jurl_error_size; i++) {
+ if (janet_keyeq(arg, jurl_errors[i].keyword)) {
+ code = jurl_errors[i].code;
+ break;
+ }
+ }
+ break;
+ case JANET_TFLAG_NUMBER:
+ code = janet_getinteger64(argv, 0); // take advantage of the macro check rather than arg
+ break;
+ default:
+ janet_panicf("expected keyword or number in jurl_strerror, got %T", janet_type(arg));
+ }
+
+ return janet_cstringv(curl_easy_strerror(code));
+}
diff --git a/main.c b/main.c
index 980e6f9..fad38d9 100644
--- a/main.c
+++ b/main.c
@@ -33,6 +33,13 @@ JANET_FN(jurl_perform,
"(jurl-native/perform handle)",
"Perform the request associated with a handle");
+// jurl_errors.c
+JANET_FN(jurl_geterror,
+ "(jurl-native/geterror :error/write-error)"
+ "\n"
+ "(jurl-native/geterror 1234)",
+ "Get an explanation string about a jurl error");
+
// jurl_getinfo.c
JANET_FN(jurl_getinfo,
"(jurl-native/getinfo handle :info)"
@@ -56,6 +63,9 @@ static const JanetRegExt cfuns[] = {
JANET_REG("global-cleanup", jurl_global_cleanup),
JANET_REG("perform", jurl_perform),
+ // jurl_errors.c
+ JANET_REG("geterror", jurl_geterror),
+
// jurl_getinfo.c
JANET_REG("getinfo", jurl_getinfo),
diff --git a/project.janet b/project.janet
index 4977689..4a40a34 100644
--- a/project.janet
+++ b/project.janet
@@ -7,7 +7,7 @@
:cflags [;default-cflags]
:lflags [;default-lflags "-lcurl" "-undefined" "error"]
:headers ["jurl.h"]
- :source ["main.c" "jurl.c" "jurl_callbacks.c" "jurl_enums.c" "jurl_getinfo.c" "jurl_setopt.c"])
+ :source ["main.c" "jurl.c" "jurl_callbacks.c" "jurl_enums.c" "jurl_errors.c" "jurl_getinfo.c" "jurl_setopt.c"])
(declare-source
:source "jurl.janet")