digitalmars.D.learn - curl: catching exception on connect.
- Suliman (55/55) Nov 30 2014 I can't understand why I am getting exception on next code:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (15/27) Nov 30 2014 In capitals to make a lasting effect: DON'T EVER OUTPUT THE EXCEPTION
- Suliman (6/6) Nov 30 2014 Am I right understand all exception are derived from
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (35/40) Dec 01 2014 No, all exceptions are derived from Throwable. It has two descendants:
- Suliman (22/22) Dec 01 2014 Big thanks Ali!
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (29/35) Dec 01 2014 std.net.curl.CurlException@C:\DMD\dmd2\windows\bin\..\..\src\phobos\std\...
- Suliman (3/6) Dec 01 2014 dlang.org should work on HTTP, but not HTTPS.
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (7/14) Dec 02 2014 connect() sends a "CONNECT" request to the server, as defined by
- Suliman (3/7) Dec 02 2014 So what is the best way to check status server response (400, 404
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (28/35) Dec 03 2014 connect() uses the curl.HTTP struct, which is available to us as well:
- Meta (16/31) Nov 30 2014 Change this here:
I can't understand why I am getting exception on next code: void downloadFile() { foreach(link; links) { try { writeln(connect(link)); } catch(Exception msg) { writeln(msg); } } } Exception text: std.net.curl.CurlException C:\DMD\dmd2\windows\bin\..\..\src\phobos\std\net\curl .d(779): HTTP request returned status code 400 ---------------- 0x0040A536 in pure safe bool std.exception.enforceEx!(std.net.curl.CurlExceptio n).enforceEx!(bool).enforceEx(bool, lazy immutable(char)[], immutable(char)[], u int) at C:\DMD\dmd2\windows\bin\..\..\src\phobos\std\exception.d(529) 0x004073EC in char[] std.net.curl._basicHTTP!(char)._basicHTTP(const(char)[], co nst(void)[], std.net.curl.HTTP) at C:\DMD\dmd2\windows\bin\..\..\src\phobos\std\ net\curl.d(784) 0x0040720C in char[] std.net.curl.connect!(char).connect(const(char)[], std.net. curl.HTTP) at C:\DMD\dmd2\windows\bin\..\..\src\phobos\std\net\curl.d(694) 0x00402386 in void app.simpleDownload.downloadFile() 0x0040206D in _Dmain at D:\code\imgDownload\source\app.d(20) 0x00437C08 in void rt.dmain2._d_run_main(int, char**, extern (C) int function(ch ar[][])*).runAll().void __lambda1() 0x00437BDB in void rt.dmain2._d_run_main(int, char**, extern (C) int function(ch ar[][])*).runAll() 0x00437AF4 in _d_run_main 0x00432FEC in main 0x0047529D in mainCRTStartup 0x7729336A in BaseThreadInitThunk 0x77A59F72 in RtlInitializeExceptionChain 0x77A59F45 in RtlInitializeExceptionChain std.net.curl.CurlException C:\DMD\dmd2\windows\bin\..\..\src\phobos\std\net\curl .d(779): HTTP request returned status code 400 By the code App should simply write the server response like 400 or 200. But it's simply crash. It's look like I do not right understand exception level and way of use them. Could anybody help me?
Nov 30 2014
This is turning out to be a common problem. :) On 11/30/2014 11:24 AM, Suliman wrote:I can't understand why I am getting exception on next code: void downloadFile() { foreach(link; links) { try { writeln(connect(link)); } catch(Exception msg) { writeln(msg);In capitals to make a lasting effect: DON'T EVER OUTPUT THE EXCEPTION OBJECT! Otherwise, you will fool yourself and others as if the exception is not being caught. What is happening is that you are actually catching the exception, printing on screen and exiting cleanly. There is no point of printing the exception object itself. Instead, print a meaningful message or something else: } catch(Exception msg) { import std.string; writeln(format("Failed to download '%s'.", link)); } Ali
Nov 30 2014
Am I right understand all exception are derived from "assertThrown" http://dlang.org/phobos/std_exception.html So "msg" in "catch(Exception msg)" is from function "assertThrown"? Could you show me example of how to handle type of exception?
Nov 30 2014
On 11/30/2014 10:38 PM, Suliman wrote:Am I right understand all exception are derived from "assertThrown" http://dlang.org/phobos/std_exception.htmlNo, all exceptions are derived from Throwable. It has two descendants: - Error, representing conditions that are irrecoverable, and - Exception, representing conditions that are recoverable. Those two have many descendants themselves. assertThrown() is useful in unit testing. It is a function that checks whether an expression indeed throws an exception.So "msg" in "catch(Exception msg)"'catch' catches an exception object. You should name it as 'exc' or something similar. 'msg' makes it sound like "message" which it is not.is from function "assertThrown"? Could you show me example of how to handle type of exception?Your example works: You are actually handling the exception. What you did with it later was confusing to you and to us. The following program realizes that a connect() call failed by catching an exception. It simply outputs a message about it. import std.stdio; import std.net.curl; pragma(lib, "curl"); const links = [ "ddili.org/non_existent_link" ]; void downloadFile() { foreach(link; links) { try { connect(link); } catch(Exception exc) { import std.string; writeln(format("Failed to download '%s'.", link)); } } } void main() { downloadFile(); } Ali
Dec 01 2014
Big thanks Ali! Only the small last question: why: string link = "dlang.org"; writeln(connect(link)); cause crash: std.net.curl.CurlException C:\DMD\dmd2\windows\bin\..\..\src\phobos\std\net\curl .d(779): HTTP request returned status code 400 ---------------- 0x00404263 0x0040226A 0x00402090 0x00402030 0x00421E6C 0x00421E3F 0x00421D58 0x0041A177 0x7641336A in BaseThreadInitThunk 0x77069F72 in RtlInitializeExceptionChain 0x77069F45 in RtlInitializeExceptionChain I remember that there was some issue in docs (if I not mistaken) but I can't google about it.
Dec 01 2014
On 12/01/2014 10:25 AM, Suliman wrote:why: string link = "dlang.org"; writeln(connect(link)); cause crash:(To be pedantic: An unhandled exception is not a crash. ;) )std.net.curl.CurlException C:\DMD\dmd2\windows\bin\..\..\src phobos\std\net\curl.d(779): HTTP request returned status code 400Indeed, the following program does behave in the same way: import std.stdio; import std.net.curl; pragma(lib, "curl"); void main() { string link = "dlang.org"; writeln(connect(link)); } I have very little experience with the HTTP protocol and its methods but I've just learnt that connect() is for HTTP's CONNECT method, which is most likely supported on port 443. So, I tried string link = "dlang.org:443"; and got std.net.curl.CurlException std/net/curl.d(3684): Server returned nothing (no headers, no data) on handle 198F860 So, that's an improvement I guess. (It was the same result at "google.com:443") Then I tried HTTPS explicitly: string link = "https://dlang.org:443"; Now the error message is more promising: std.net.curl.CurlException std/net/curl.d(3684): Peer certificate cannot be authenticated with known CA certificates on handle 1653860 My guess is that you have to use HTTPS for CONNECT and that you have to have credentials for it. (?) Ali
Dec 01 2014
My guess is that you have to use HTTPS for CONNECT and that you have to have credentials for it. (?) Alidlang.org should work on HTTP, but not HTTPS. Also I do not think that when I connect to HTTPS I should have any credentials. It's mostly like issue with curl...
Dec 01 2014
On Monday, 1 December 2014 at 19:44:56 UTC, Suliman wrote:connect() sends a "CONNECT" request to the server, as defined by HTTP [1]. This method is only used when you're working with proxies and the like. What you most likely want, however, is a "GET" request. Use get() for that. [1] https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methodsMy guess is that you have to use HTTPS for CONNECT and that you have to have credentials for it. (?) Alidlang.org should work on HTTP, but not HTTPS. Also I do not think that when I connect to HTTPS I should have any credentials. It's mostly like issue with curl...
Dec 02 2014
connect() sends a "CONNECT" request to the server, as defined by HTTP [1]. This method is only used when you're working with proxies and the like. What you most likely want, however, is a "GET" request. Use get() for that.So what is the best way to check status server response (400, 404 etc) to send get request and try to parse response, or there is any better way (probably with another lib?)?
Dec 02 2014
On 12/02/2014 05:19 AM, Suliman wrote:connect() uses the curl.HTTP struct, which is available to us as well: http://dlang.org/phobos/std_net_curl.html#HTTP I added two lines to the first example there: import std.net.curl, std.stdio; pragma(lib, "curl"); void main() { // Get with custom data receivers auto http = HTTP("dlang.org"); http.onReceiveHeader = (in char[] key, in char[] value) { writeln(key ~ ": " ~ value); }; http.onReceive = (ubyte[] data) { /+ drop +/ return data.length; }; http.perform(); const HTTP.StatusLine statusLine = http.statusLine(); writefln("GET request completed with code %s", statusLine.code); } Sample output: date: Wed, 03 Dec 2014 18:19:15 GMT server: Apache/2.2.22 (FreeBSD) PHP/5.3.15 with Suhosin-Patch mod_ssl/2.2.22 OpenSSL/0.9.8x DAV/2 last-modified: Sun, 02 Nov 2014 06:38:55 GMT etag: "3b438-4f9a-506da7be81dc0" accept-ranges: bytes content-length: 20378 content-type: text/html GET request completed with code 200 Aliconnect() sends a "CONNECT" request to the server, as defined by HTTP [1]. This method is only used when you're working with proxies and the like. What you most likely want, however, is a "GET" request. Use get() for that.So what is the best way to check status server response (400, 404 etc) to send get request and try to parse response, or there is any better way (probably with another lib?)?
Dec 03 2014
On Sunday, 30 November 2014 at 19:24:39 UTC, Suliman wrote:I can't understand why I am getting exception on next code: void downloadFile() { foreach(link; links) { try { writeln(connect(link)); } catch(Exception msg) { writeln(msg); } } }Change this here: catch (Exception msg) { writeln(msg); } to: catch (Exception msg) { writeln(msg.msg); } The problem is that you are catching the exception and then printing it out, which prints a string representation of the exception. This string representation includes the exception's message and its stack trace. What you probably want is to print out its .msg member, which is the error message.
Nov 30 2014