about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-06-19 20:56:06 +0200
committerbptato <nincsnevem662@gmail.com>2023-06-19 20:56:06 +0200
commitb3e08ac443d5d010938be7ae9b9bf8c04ca55300 (patch)
treed6c4ed711fa6553a95ae7b1b2e77d1d5d4926bd2 /src
parent82fb1f70ab275884c42dd769b2af8f9df5389e88 (diff)
downloadchawan-b3e08ac443d5d010938be7ae9b9bf8c04ca55300.tar.gz
Reject fetch promise on network error
Instead of setting the non-standard res variable.
Diffstat (limited to 'src')
-rw-r--r--src/buffer/buffer.nim29
-rw-r--r--src/display/client.nim2
-rw-r--r--src/html/dom.nim7
-rw-r--r--src/html/env.nim2
-rw-r--r--src/io/loader.nim16
-rw-r--r--src/io/response.nim2
-rw-r--r--src/js/javascript.nim2
7 files changed, 33 insertions, 27 deletions
diff --git a/src/buffer/buffer.nim b/src/buffer/buffer.nim
index 74f0545e..e8f8eaaa 100644
--- a/src/buffer/buffer.nim
+++ b/src/buffer/buffer.nim
@@ -34,6 +34,7 @@ import io/window
 import ips/serialize
 import ips/serversocket
 import ips/socketstream
+import js/javascript
 import js/regex
 import js/timeout
 import layout/box
@@ -560,14 +561,15 @@ proc loadResource(buffer: Buffer, elem: HTMLLinkElement): EmptyPromise =
       let cvals = parseListOfComponentValues(newStringStream(media))
       let media = parseMediaQueryList(cvals)
       if not media.applies(document.window): return
-    return buffer.loader.fetch(newRequest(url)).then(proc(res: Response):
-        Opt[Promise[string]] =
-      if res.res == 0: #TODO remove res
-        #TODO we should use ReadableStreams for this (which would allow us to
-        # parse CSS asynchronously)
-        if res.contenttype == "text/css":
-          return ok(res.text())
-        res.unregisterFun()
+    return buffer.loader.fetch(newRequest(url))
+      .then(proc(res: Result[Response, JSError]): Opt[Promise[string]] =
+        if res.isOk:
+          let res = res.get
+          #TODO we should use ReadableStreams for this (which would allow us to
+          # parse CSS asynchronously)
+          if res.contenttype == "text/css":
+            return ok(res.text())
+          res.unregisterFun()
       ).then(proc(s: Opt[string]) =
         if s.isOk:
           #TODO this is extremely inefficient, and text() should return
@@ -585,10 +587,13 @@ proc loadResource(buffer: Buffer, elem: HTMLImageElement): EmptyPromise =
   let url = parseURL(src, document.url.some)
   if url.isSome:
     let url = url.get
-    return buffer.loader.fetch(newRequest(url)).then(proc(res: Response): Promise[string] =
-      if res.contenttype == "image/png":
-        #TODO using text() for PNG is wrong
-        return res.text()
+    return buffer.loader.fetch(newRequest(url))
+      .then(proc(res: Result[Response, JSError]): Promise[string] =
+        if res.isOk:
+          let res = res.get
+          if res.contenttype == "image/png":
+            #TODO using text() for PNG is wrong
+            return res.text()
     ).then(proc(pngData: string) =
       elem.bitmap = fromPNG(toOpenArrayByte(pngData, 0, pngData.high)))
 
diff --git a/src/display/client.nim b/src/display/client.nim
index af4b3fb2..1c9e0b1f 100644
--- a/src/display/client.nim
+++ b/src/display/client.nim
@@ -91,7 +91,7 @@ proc `=destroy`(client: var ClientObj) =
 proc doRequest(client: Client, req: Request): Response {.jsfunc.} =
   return client.loader.doRequest(req)
 
-proc fetch(client: Client, req: Request): Promise[Response] {.jsfunc.} =
+proc fetch(client: Client, req: Request): FetchPromise {.jsfunc.} =
   return client.loader.fetch(req)
 
 proc interruptHandler(rt: JSRuntime, opaque: pointer): int {.cdecl.} =
diff --git a/src/html/dom.nim b/src/html/dom.nim
index 1fa3b043..3bf67b05 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -2396,14 +2396,13 @@ proc fetchClassicScript(element: HTMLScriptElement, url: URL,
     let loader = element.document.window.loader
     if loader.isSome:
       let request = createPotentialCORSRequest(url, RequestDestination.SCRIPT, cors)
-      loader.get.fetch(request).then(proc(r: Response): auto =
-        if r.res != 0 or r.body == nil:
-          #TODO remove res
+      loader.get.fetch(request).then(proc(r: Result[Response, JSError]): auto =
+        if r.isErr or r.get.body == nil:
           element.onComplete(ScriptResult(t: RESULT_NULL))
         else:
           #TODO use charset from content-type
           #TODO text() should decode
-          return r.text()
+          return r.get.text()
       ).then(proc(s: string) =
         let ss = newStringStream(s) #TODO unnecessary copy
         let cs = if cs == CHARSET_UNKNOWN: CHARSET_UTF_8 else: cs
diff --git a/src/html/env.nim b/src/html/env.nim
index a70508be..eba067a8 100644
--- a/src/html/env.nim
+++ b/src/html/env.nim
@@ -61,7 +61,7 @@ proc addNavigatorModule(ctx: JSContext) =
   ctx.registerType(PluginArray)
   ctx.registerType(MimeTypeArray)
 
-proc fetch(window: Window, req: Request): Promise[Response] {.jsfunc.} =
+proc fetch(window: Window, req: Request): FetchPromise {.jsfunc.} =
   if window.loader.isSome:
     return window.loader.get.fetch(req)
 
diff --git a/src/io/loader.nim b/src/io/loader.nim
index 1b5d8847..9f2682d9 100644
--- a/src/io/loader.nim
+++ b/src/io/loader.nim
@@ -31,6 +31,7 @@ import io/urlfilter
 import ips/serialize
 import ips/serversocket
 import ips/socketstream
+import js/exception
 import js/javascript
 import types/cookie
 import types/mime
@@ -51,7 +52,7 @@ type
     unregisterFun*: proc(fd: int)
 
   ConnectData = object
-    promise: Promise[Response]
+    promise: Promise[Result[Response, JSError]]
     stream: Stream
     request: Request
 
@@ -83,6 +84,8 @@ type
     cookiejar*: CookieJar
     referrerpolicy*: ReferrerPolicy
 
+  FetchPromise* = Promise[Result[Response, JSError]]
+
 converter toInt*(code: ConnectErrorCode): int =
   return int(code)
 
@@ -249,14 +252,14 @@ proc applyHeaders(request: Request, response: Response) =
             destination = request.destination)
 
 #TODO: add init
-proc fetch*(loader: FileLoader, input: Request): Promise[Response] =
+proc fetch*(loader: FileLoader, input: Request): FetchPromise =
   let stream = connectSocketStream(loader.process, false, blocking = true)
   stream.swrite(LOAD)
   stream.swrite(input)
   stream.flush()
   let fd = int(stream.source.getFd())
   loader.registerFun(fd)
-  let promise = Promise[Response]()
+  let promise = FetchPromise()
   loader.connecting[fd] = ConnectData(
     promise: promise,
     request: input,
@@ -292,13 +295,12 @@ proc onConnected*(loader: FileLoader, fd: int) =
       readbufsize: BufferSize,
     )
     SocketStream(stream).source.getFd().setBlocking(false)
-    promise.resolve(response)
+    promise.resolve(Result[Response, JSError].ok(response))
   else:
     loader.unregisterFun(fd)
     loader.unregistered.add(fd)
-    #TODO: reject promise instead.
-    let response = newResponse(res, request)
-    promise.resolve(response)
+    let err = newTypeError("NetworkError when attempting to fetch resource")
+    promise.resolve(Result[Response, JSError].err(err))
   loader.connecting.del(fd)
 
 proc onRead*(loader: FileLoader, fd: int) =
diff --git a/src/io/response.nim b/src/io/response.nim
index 7d0f789a..ae418318 100644
--- a/src/io/response.nim
+++ b/src/io/response.nim
@@ -11,7 +11,7 @@ type
     fd*: int
     body*: Stream
     bodyUsed* {.jsget.}: bool
-    res* {.jsget.}: int
+    res*: int
     contenttype* {.jsget.}: string
     status* {.jsget.}: int
     headers* {.jsget.}: Headers
diff --git a/src/js/javascript.nim b/src/js/javascript.nim
index ced12bf7..c1028537 100644
--- a/src/js/javascript.nim
+++ b/src/js/javascript.nim
@@ -932,7 +932,7 @@ proc toJS[T, E](ctx: JSContext, promise: Promise[Result[T, E]]): JSValue =
       let x = when E is void:
         JS_UNDEFINED
       else:
-        toJS(ctx, x.get)
+        toJS(ctx, x.error)
       let res = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, 1, unsafeAddr x)
       JS_FreeValue(ctx, res)
       JS_FreeValue(ctx, x)