I need a little help with extending futures with additional context for error reporting. I can't even get my current effort to compile without commenting out a couple lines :-(.
Any pointers would certainly be appreciated.
# Background:
# - Test harness to check out how to extend a httpclient future to include
#   additional context information (in this case the source url which could be
#   usefull in reporting failures)
import asyncdispatch, httpclient, strutils, system
type URLinfo = object
  url: string
  content: string
# Non-working attempt to implement the extended future
proc fetch(url: string): Future[URLinfo] {.async.} =
  var fetchResult = URLinfo()
  var extendedFuture = newFuture[URLinfo]
  var client = newAsyncHttpClient()
  
  fetchResult.url = url
  let future = client.getContent url
  
  # Use subordinate *simple* http future completon to trigger the *extended* future
  future.addCallback(
    proc(future: Future[string]) =
      fetchResult.content = future.read
      echo "content: ", fetchResult.content.len
#     complete(extendedFuture, fetchResult) # doesn't compile
   )
  
  discard await future
# result = extendedFuture # doesn't compile
  echo "fetch finished"
proc getURLs(urls: seq[string]) : Future[seq[URLinfo]] {.async.} =
  var futures: seq[Future[URLinfo]]
  
  for url in urls:
    var future = fetch url
    futures.add future
  
  result = await all futures
  echo "getURLs finished"
proc main() {.async} =
  const sites = @[
    "https://google.com",
    "https://amazon.com"
  ]
  discard await getURLs sites
waitFor main()
echo "main finished"
This should work. Extending Future are more straightforward
# Background:
# - Test harness to check out how to extend a httpclient future to include
#   additional context information (in this case the source url which could be
#   usefull in reporting failures)
import std/[asyncdispatch, httpclient, strutils]
type URLinfo = object
  url: string
  content: string
# Non-working attempt to implement the extended future
proc fetch(url: string): Future[URLinfo] {.async.} =
  let
    client = newAsyncHttpClient()
    future = await client.getContent url
  result =  URLInfo(url: url, content: future)
  echo "fetch finished for url: ", url
proc getURLs(urls: seq[string]) : Future[seq[URLinfo]] {.async.} =
  var futures: seq[Future[URLinfo]]
  
  for url in urls:
    var future = fetch url
    futures.add future
  
  result = await all futures
  echo "getURLs finished"
proc main() {.async} =
  const sites = @[
    "https://google.com",
    "https://youtube.com",
    "https://facebook.com",
    "https://twitter.com",
    "https://nim-lang.org",
    "https://reddit.com",
    "https://amazon.com"
  ]
  discard await getURLs sites
waitFor main()
echo "main finished"
From this code it does:
# Background:
# - Test harness to check out how to extend a httpclient future to include
#   additional context information (in this case the source url which could be
#   usefull in reporting failures)
import std/[asyncdispatch, httpclient, times, strformat, strutils]
type URLinfo = object
  url: string
  content: string
# Non-working attempt to implement the extended future
proc fetch(url: string): Future[URLinfo] {.async.} =
  let
    startTime = now()
    client = newAsyncHttpClient()
    future = await client.getContent url
  result = URLInfo(url: url, content: future)
  echo &"fetch finished for url: {url}\n\t from {startTime}\n\tuntil {now()}"
proc getURLs(urls: seq[string]) : Future[seq[URLinfo]] {.async.} =
  var futures: seq[Future[URLinfo]]
  
  for url in urls:
    var future = fetch url
    futures.add future
  
  result = await all futures
  echo "getURLs finished"
proc main() =
  const sites = @[
    "https://google.com",
    "https://youtube.com",
    "https://facebook.com",
    "https://twitter.com",
    "https://nim-lang.org",
    "https://reddit.com",
    "https://amazon.com"
  ]
  discard waitFor getURLs sites
main()
echo "main finished"