From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 5C0397EE6B for ; Mon, 2 Dec 2013 04:46:23 +0100 (CET) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of milanst@gmail.com) identity=pra; client-ip=209.85.223.173; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="milanst@gmail.com"; x-sender="milanst@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of milanst@gmail.com designates 209.85.223.173 as permitted sender) identity=mailfrom; client-ip=209.85.223.173; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="milanst@gmail.com"; x-sender="milanst@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-ie0-f173.google.com) identity=helo; client-ip=209.85.223.173; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="milanst@gmail.com"; x-sender="postmaster@mail-ie0-f173.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AjsDAPcBnFLRVd+tlGdsb2JhbABZDoMxU4J6oxSSSYEWCBYOAQEBAQcLCwkSKoIlAQEEASMEGQELEB0BAwELBgULCAUCAiYCAiIBAg8BBQEcBhMIh2YBAwkCBA2idYwGU4MJgQWCbAoZJw1khlARAQUMgR2McjozB4JrgUgDiUKOUpAmGCmEFl0e X-IPAS-Result: AjsDAPcBnFLRVd+tlGdsb2JhbABZDoMxU4J6oxSSSYEWCBYOAQEBAQcLCwkSKoIlAQEEASMEGQELEB0BAwELBgULCAUCAiYCAiIBAg8BBQEcBhMIh2YBAwkCBA2idYwGU4MJgQWCbAoZJw1khlARAQUMgR2McjozB4JrgUgDiUKOUpAmGCmEFl0e X-IronPort-AV: E=Sophos;i="4.93,807,1378850400"; d="scan'208";a="46412990" Received: from mail-ie0-f173.google.com ([209.85.223.173]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 02 Dec 2013 04:46:22 +0100 Received: by mail-ie0-f173.google.com with SMTP id to1so19296548ieb.4 for ; Sun, 01 Dec 2013 19:46:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type:content-transfer-encoding; bh=UoibfjOUpsVmhWSqi7jFjwtYveQjewpyuyK0tQy4Rqg=; b=AcBT5aOP69zrRhnxb5/BJHaKo5cdd5PvK2OJSTxI/5gw6tabpg7Cx8+srCCZYiGAsw HDwiGF3kR0j+7NJSa1Ak2qnSxvw1dsGlANV95vKep0rxYmAywFaGYoRg+2nZ37PLPycU nIN2XgwWbzMS5I1CCXvRSJSIjZ8X90JeZfkiXPdfB3Dkt+VledSV1IBfmWD9XVbRw5Bf 55V6OLqOdUOoeaWevHU7Q4dkj7mIkCh7tSTm6mp9EC7W+0UmIMQYS4XvN6Q6690gLMSX F/FBMyh8YP2UP3IcStn8iwBC6lb486XIXwI1VWbYcxVzI91tp60dmmXUZTGhKsEajOKi zHWw== X-Received: by 10.42.62.196 with SMTP id z4mr11182ich.49.1385955980919; Sun, 01 Dec 2013 19:46:20 -0800 (PST) MIME-Version: 1.0 Received: by 10.64.63.11 with HTTP; Sun, 1 Dec 2013 19:45:40 -0800 (PST) In-Reply-To: <96620953-9991-4976-A207-7DBB32584D57@my.bristol.ac.uk> References: <96620953-9991-4976-A207-7DBB32584D57@my.bristol.ac.uk> From: =?UTF-8?Q?Milan_Stanojevi=C4=87?= Date: Sun, 1 Dec 2013 22:45:40 -0500 Message-ID: To: Ollie Frolovs Cc: caml users Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [Caml-list] Extracting exception details (Async, Cohttp, Exn) On Fri, Nov 29, 2013 at 9:34 AM, Ollie Frolovs wrote: > Hello list! > > I=E2=80=99m designing a function to query a web service and i am stuck tr= ying to implement quality error handling/reporting. I have a specific quest= ion =E2=80=93 how do i extract the =E2=80=9Cdescription=E2=80=9D field from= the Core=E2=80=99s Exn type? > There is no "description" field in Exn type. The confusion here is that the exception you see is actually a wrapped async exception. When async catches an exception, it wraps it up in a different exception with more information for easier debugging. Its definition is (you can see it at https://github.com/janestreet/async_core/blob/master/lib/monitor.ml#L55) module Exn_for_monitor =3D struct type t =3D { exn : exn; backtrace : string sexp_list; backtrace_history : Backtrace.t sexp_list; monitor : monitor; } with fields, sexp_of end exception Error_ of Exn_for_monitor.t with sexp And that is what you see in your output. To get the original exception you can use Monitor.extract_exn but that gives you less information (but it might be ok in your particular case) > I=E2=80=99ve been experimenting in the top-level and i got stuck. My work= flow with step by step explanations is below. > > > First, i create a request, which i believe does not run just yet because = it is =E2=80=9Cdeferred=E2=80=9D. > > utop # let result =3D try_with (fun () -> Cohttp_async.Client.get (Uri.of= _string "http://127.0.0.2"));; > val result : (Cohttp.Response.t * string Pipe.Reader.t, exn) Result.t Def= erred.t =3D > > Then, i =E2=80=9CDeferred.map" the result at which point the Cohttp/Async= library try to connect and (as desired) fail. utop has some special support for async but I'm not sure exactly what it does but I doubt it delays running a function. In general when you have a function in async that returns a deferred, you do kick off code that will eventually fill in the deferred that you got back. It is not the case that only when you use that deferred something happens. Just wanted to point this out to avoid misconceptions about async. > I had a look at Core=E2=80=99s documentation for Exn but its to_string re= turns the whole sexp converted into string so i am stuck :=E2=80=99( > > As a side question for someone familiar with Core =E2=80=93 why does Exn.= to_string return sexp in a string at all, it also has sexp_of_t, so i suppo= se one could evaluate Sexp.to_string @@ Exn.sexp_of_t e. I am surprised tha= t i do not see a function to extract the valuable description field from t= he exception and yet there is this apparent duplication of effort. Or am i = talking non-sense? > As I said before, this is an issue with async wrapping the original exception with some more data and then raising the new exception. Exn.to_string gives you a sexp in a string precisely to avoid duplication of effort. Otherwise we would need to write to_string and sexp_of_t for each exception (basically having two preprocessors, one for to_string and one for sexp). This way you just define your exception and add "with sexp" and you get all the data in exception when it's raised. Hope this helps, Milan