<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div style=""
data-md-original="On%2021%2F05%2F14%2010%3A07%2C%20Klaus%20Darilion%20wrote%3A%3Cbr%3E%26gt%3B%20Thanks.%20Meanwhile%20I%20managed%20to%20iterate%20over%20the%20JSON%20list%20and%20print%20the%3Cbr%3E%26gt%3B%20nsid%3A%3Cbr%3E%26gt%3B%3Cbr%3E%26gt%3B%20...%3Cbr%3E%26gt%3B%3Cbr%3E%26gt%3B%20But%20the%20problem%20is%20if%20there%20was%20an%20error%20during%20the%20measurement%20(eg%3Cbr%3E%26gt%3B%20timeout)%2C%20then%20my%20script%20terminates%3A%3Cbr%3E%26gt%3B%3Cbr%3E%26gt%3B%20...%3Cbr%3E%26gt%3B%3Cbr%3E%26gt%3B%20What%20is%20the%20suggested%20way%20to%20find%20out%20if%20a%20result%20is%20valid%20and%20exists%3F%3Cbr%3E%3Cbr%3E%3Cbr%3EFirst%20of%20all%2C%20i%20should%20say%20thanks%20for%20working%20with%20us%20on%20this.%C2%A0%20The%20trouble%20with%20a%20parsing%20library%20is%20that%20it's%20supposed%20to%20be%20able%20to%20handle%20all%20of%20the%20edge%20cases%2C%20but%20finding%20them%20independently%20is%20quite%20difficult.%C2%A0%20When%20you%20post%20examples%20to%20the%20
list%20of%20result%20blobs%20that%20act%20in%20unexpected%20ways%2C%20this%20really%20helps%20in%20polishing%20the%20parser%20and%20making%20it%20more%20intuitive.%3Cbr%3E%3Cbr%3EGiven%20that%2C%20and%20other%20comments%20from%20John%20regarding%20error%20handling%20for%20DNS%20results%2C%20I've%20added%20a%20little%20more%20code%20to%20better%20handle%20errors%2C%20so%20if%20you%20update%20Sagan%20to%200.1.12%20(or%20just%20%60git%20pull%60)%2C%20and%20re-run%20your%20code%20you'll%20find%20that%20%60result.is_error%60%20is%20now%20set%20to%20%60True%60%20in%20your%20case.%C2%A0%20Additionally%2C%20if%20you%20pass%20%60on_error%3DResult.ERROR_FAIL%60%20to%20the%20parsing%20argument%2C%20it'll%20explode%20with%20a%20%60ResultParseError%60%20which%20you%20can%20handle%20any%20way%20you%20please.%3Cbr%3E%3Cbr%3ESo%20given%20your%20example%2C%20you%20could%20do%20something%20like%3A%3Cbr%3E%3Cbr%3E%60%60%60python%3Cbr%3E%C2%A0%C2%A0%C2%A0%20result%20%3D%20DnsResult(d)%3Cbr%3E%C2%A0%C2%A0
%C2%A0%20if%20not%20result.is_error%3A%3Cbr%3E%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20%23%20Do%20stuff%3Cbr%3E%60%60%60%3Cbr%3E%3Cbr%3EHowever%2C%20there's%20likely%20cases%20where%20you%20might%20see%20results%20that%20*aren't*%20errors%2C%20but%20still%20don't%20have%20any%20responses%2C%20or%20where%20%60edns0.options%60%20is%20an%20empty%20list.%C2%A0%20Unfortunately%2C%20you%20have%20to%20write%20your%20code%20to%20account%20for%20these%2C%20since%20they're%20perfectly%20valid%20parsings%3A%3Cbr%3E%3Cbr%3E%60%60%60python%3Cbr%3E%C2%A0%C2%A0%C2%A0%20result%20%3D%20DnsResult(d)%3Cbr%3E%C2%A0%C2%A0%C2%A0%20if%20not%20result.is_error%3A%3Cbr%3E%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20for%20response%20in%20responses%3A%3Cbr%3E%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20if%20response.edns0%3A%3Cbr%3E%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20for%20option%20in%20response.edns0.options%3A%3Cbr%3E%C2%A0%C2
%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%20print(option.nsid)%3Cbr%3E%60%60%60%3Cbr%3E%3Cbr%3ENote%20that%20I'm%20not%20really%20checking%20that%20much%20here%2C%20just%20looping%20over%20(potentially%20empty)%20lists.%C2%A0%20This%20keeps%20your%20code%20free%20of%20checks%2C%20and%20will%20make%20sure%20that%20it%20accounts%20for%20cases%20where%20the%20number%20of%20responses%20is%20%26gt%3B%201%20or%20the%20number%20of%20edns0%20options%20is%20%26gt%3B%201.%3Cbr%3E%3Cbr%3EBut%20please%2C%20if%20you%20find%20another%20result%20blob%20that%20isn't%20performing%20the%20way%20you'd%20expect%2C%20please%20feel%20free%20to%20post%20it%20here%20or%20send%20it%20to%20atlas-bugs%40ripe.net%20so%20we%20can%20look%20into%20it%20and%20make%20sure%20that%20Sagan%20has%20complete%20coverage.%3Cbr%3E"
      class="markdown-here-wrapper" data-md-url="Thunderbird"
      id="markdown-here-wrapper-662896">
      <p style="margin: 1.2em 0px ! important;">On 21/05/14 10:07, Klaus
        Darilion wrote:</p>
      <blockquote style="margin: 1.2em 0px;border-left: 4px solid
        rgb(221, 221, 221); padding: 0px 1em; color: rgb(119, 119, 119);
        quotes: none;">
        <p style="margin: 1.2em 0px ! important;">Thanks. Meanwhile I
          managed to iterate over the JSON list and print the<br>
          nsid:</p>
        <p style="margin: 1.2em 0px ! important;">…</p>
        <p style="margin: 1.2em 0px ! important;">But the problem is if
          there was an error during the measurement (eg<br>
          timeout), then my script terminates:</p>
        <p style="margin: 1.2em 0px ! important;">…</p>
        <p style="margin: 1.2em 0px ! important;">What is the suggested
          way to find out if a result is valid and exists?</p>
      </blockquote>
      <p style="margin: 1.2em 0px ! important;">First of all, i should
        say thanks for working with us on this. The trouble with a
        parsing library is that it’s supposed to be able to handle all
        of the edge cases, but finding them independently is quite
        difficult. When you post examples to the list of result blobs
        that act in unexpected ways, this really helps in polishing the
        parser and making it more intuitive.</p>
      <p style="margin: 1.2em 0px ! important;">Given that, and other
        comments from John regarding error handling for DNS results,
        I’ve added a little more code to better handle errors, so if you
        update Sagan to 0.1.12 (or just <code style="font-family:
          Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em;
          padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid
          rgb(234, 234, 234); background-color: rgb(248, 248, 248);
          border-radius: 3px 3px 3px 3px; display: inline;">git pull</code>),
        and re-run your code you’ll find that <code style="font-family:
          Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em;
          padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid
          rgb(234, 234, 234); background-color: rgb(248, 248, 248);
          border-radius: 3px 3px 3px 3px; display: inline;">result.is_error</code>
        is now set to <code style="font-family:
          Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em;
          padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid
          rgb(234, 234, 234); background-color: rgb(248, 248, 248);
          border-radius: 3px 3px 3px 3px; display: inline;">True</code>
        in your case. Additionally, if you pass <code
          style="font-family:
          Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em;
          padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid
          rgb(234, 234, 234); background-color: rgb(248, 248, 248);
          border-radius: 3px 3px 3px 3px; display: inline;">on_error=Result.ERROR_FAIL</code>
        to the parsing argument, it’ll explode with a <code
          style="font-family:
          Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em;
          padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid
          rgb(234, 234, 234); background-color: rgb(248, 248, 248);
          border-radius: 3px 3px 3px 3px; display: inline;">ResultParseError</code>
        which you can handle any way you please.</p>
      <p style="margin: 1.2em 0px ! important;">So given your example,
        you could do something like:</p>
      <pre style="font-family: Consolas,Inconsolata,Courier,monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px 3px 3px 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px 3px 3px 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block ! important;display: block; padding: 0.5em; color: rgb(51, 51, 51);" class="language-python">    result = DnsResult(d)
    <span style="color: rgb(51, 51, 51); font-weight: bold;" class="keyword">if</span> <span style="color: rgb(51, 51, 51); font-weight: bold;" class="keyword">not</span> result.is_error:
        <span style="color: rgb(153, 153, 136); font-style: italic;" class="comment"># Do stuff</span>
</code></pre>
      <p style="margin: 1.2em 0px ! important;">However, there’s likely
        cases where you might see results that <em>aren’t</em> errors,
        but still don’t have any responses, or where <code
          style="font-family:
          Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em;
          padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid
          rgb(234, 234, 234); background-color: rgb(248, 248, 248);
          border-radius: 3px 3px 3px 3px; display: inline;">edns0.options</code>
        is an empty list. Unfortunately, you have to write your code to
        account for these, since they’re perfectly valid parsings:</p>
      <pre style="font-family: Consolas,Inconsolata,Courier,monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px 3px 3px 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px 3px 3px 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block ! important;display: block; padding: 0.5em; color: rgb(51, 51, 51);" class="language-python">    result = DnsResult(d)
    <span style="color: rgb(51, 51, 51); font-weight: bold;" class="keyword">if</span> <span style="color: rgb(51, 51, 51); font-weight: bold;" class="keyword">not</span> result.is_error:
        <span style="color: rgb(51, 51, 51); font-weight: bold;" class="keyword">for</span> response <span style="color: rgb(51, 51, 51); font-weight: bold;" class="keyword">in</span> responses:
            <span style="color: rgb(51, 51, 51); font-weight: bold;" class="keyword">if</span> response.edns0:
                <span style="color: rgb(51, 51, 51); font-weight: bold;" class="keyword">for</span> option <span style="color: rgb(51, 51, 51); font-weight: bold;" class="keyword">in</span> response.edns0.options:
                    print(option.nsid)
</code></pre>
      <p style="margin: 1.2em 0px ! important;">Note that I’m not really
        checking that much here, just looping over (potentially empty)
        lists. This keeps your code free of checks, and will make sure
        that it accounts for cases where the number of responses is >
        1 or the number of edns0 options is > 1.</p>
      <p style="margin: 1.2em 0px ! important;">But please, if you find
        another result blob that isn’t performing the way you’d expect,
        please feel free to post it here or send it to
        <a class="moz-txt-link-abbreviated" href="mailto:atlas-bugs@ripe.net">atlas-bugs@ripe.net</a> so we can look into it and make sure that
        Sagan has complete coverage.</p>
    </div>
  </body>
</html>