-module(gftp@result). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/gftp/result.gleam"). -export([describe_error/1]). -export_type([ftp_error/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " Error types and result aliases for gftp operations.\n" "\n" " All gftp functions return `FtpResult(a)` which is `Result(a, FtpError)`.\n" "\n" " ```gleam\n" " import gftp\n" " import gftp/result\n" "\n" " case gftp.cwd(client, \"/nonexistent\") {\n" " Ok(_) -> // success\n" " Error(err) -> {\n" " let msg = result.describe_error(err)\n" " // \"Unexpected response: [requested action not taken; file unavailable] ...\"\n" " }\n" " }\n" " ```\n" ). -type ftp_error() :: {connection_error, mug:connect_error()} | {unexpected_response, gftp@response:response()} | bad_response | {tls, kafein:error()} | {socket, mug:error()} | data_transfer_in_progress. -file("src/gftp/result.gleam", 43). -spec connection_error_to_string(mug:connect_error()) -> binary(). connection_error_to_string(E) -> case E of {connect_failed_ipv4, E@1} -> mug:describe_error(E@1); {connect_failed_ipv6, E@2} -> mug:describe_error(E@2); {connect_failed_both, E@3, _} -> mug:describe_error(E@3) end. -file("src/gftp/result.gleam", 58). ?DOC( " Convert an `FtpError` to a human-readable string.\n" "\n" " ```gleam\n" " let msg = result.describe_error(err)\n" " // e.g. \"Connection error: Connection refused\"\n" " // e.g. \"Unexpected response: [user not logged in] Login required\"\n" " ```\n" ). -spec describe_error(ftp_error()) -> binary(). describe_error(Err) -> case Err of {connection_error, E} -> <<"Connection error: "/utf8, (connection_error_to_string(E))/binary>>; {unexpected_response, R} -> <<"Unexpected response: "/utf8, (gftp@response:describe(R))/binary>>; bad_response -> <<"Bad response syntax"/utf8>>; {socket, E@1} -> <<"Socket error: "/utf8, (mug:describe_error(E@1))/binary>>; {tls, E@2} -> <<"TLS error"/utf8, (case E@2 of closed -> <<": connection closed"/utf8>>; timeout -> <<": timeout reached"/utf8>>; {other, _} -> <<": an error occurred during TLS operation"/utf8>>; {posix_error, E@3} -> <<": "/utf8, (mug:describe_error(E@3))/binary>>; {cipher_suite_not_recognized, E@4} -> <<": cipher suite not recognized: "/utf8, E@4/binary>>; {tls_alert, _, Description} -> <<": TLS alert: "/utf8, Description/binary>> end)/binary>>; data_transfer_in_progress -> <<"Data transfer in progress: close the data channel before issuing control commands"/utf8>> end.