I am trying to figure out the best way to have reusable code with different error conditions. Below is a sample of a reusable function to execute network requests. In most languages you can throw/catch errors. There is nothing like that in BS. So what do you do when you get a non 2xx message back from an api and you want to use their message in the payload? How does the calling function know that the was an error? I really don't want to have the boilerplate code below everywhere in my app.
function request(url As String, body as string, httpType as string) as Object ' ? "POST URL :"; url ' ? "POST BODY :"; body obj = CreateObject("roUrlTransfer") obj.setUrl(url) obj.setRequest(httpType) obj.setCertificatesFile("common:/certs/ca-bundle.crt") obj.addHeader("ws-api", m.global.apiVersion) obj.addHeader("app", m.global.app) obj.addHeader("user-agent", m.global.userAgent) obj.setPort(CreateObject("roMessagePort")) obj.addHeader("Content-Type", "application/x-www-form-urlencoded") obj.enableEncodings(true)
if (m.global.authToken <> invalid and m.global.authToken <> "") obj.addHeader("authorization", "Bearer " + m.global.authToken) end if
if (obj.AsyncPostFromString(body)) msg = wait(10000, obj.GetPort()) if (type(msg) = "roUrlEvent") code = msg.GetResponseCode() ? "response code "; code
if (code = 200) ? msg.GetString() return msg.GetString() else ' error case return msg.GetString() endif else if (msg = invalid) request.AsyncCancel() endif endif
I have chosen to use multiple small tasks that all use some helper functions like the one above.
Even if I read the response body and return that from the above function, the caller would not know if it was an error or not. I am now thinking about returning a object with a status and response. Heck, maybe I should just return the message itself.
There are so many ways to design this, but personally I use a task with a `response` field and an `error` field, and the clients will observe both. I include the HTTP code and the body of the response for both.