Should you check both pcall success and HTTP response success?

I have a simple HttpService:RequestAsync call and want to determine if everything ran accordingly without any errors. In the following code I have success1 and success2 and I want to know if both is necessary. Is it possible for one to be true and the other to be false? If not, I could use one success boolean instead of two.

local function asyncCall(): boolean
    local success1: boolean = false
    
    local success2: boolean, message: string = pcall(function()
        local response = HttpService:RequestAsync {
            -- stuff here
        }
        
        success1 = response.Success
        
        if not success1 then
            print("The response returned an error:", response.StatusCode, response.StatusMessage)
        end
    end)
    
    if not success2 then
        print("The Http request failed to send:", message)
    end
    
    return success1 and success2
end

You dont need having both of them

local RequestAsync = HttpService.RequestAsync 
local JSONEncode = HttpService.JSONEncode

local function asyncCall(): boolean
    local success1: boolean, message: string = pcall(RequestAsync ,HttpService,JSONEncode{--[[Code here]]})
 
        if not success1 then
            print("The response returned an error:", message)
return false--[[or success1]]
        end
    success1 = response.Success

    return success1
end

Why is there no need to have both? Will the pcall success boolean always be the same as response.Success?

I do think you need both because in the case where the server you sent a request to has an error, it might send back a 500 Internal Server Error. In that case, RequestAsync succeeded, but the request itself didn’t, so success1 would be true, but success2 would be false

However, I am not quite sure, and you should test it yourself. You can try sending a request to some api that requires authorization, to force a 401 Unauthorized error, or you could try sending malformed data. I could test it myself as I’ve made a small proxy some time ago (I could make it send back an error code every time), if you need some help figuring this out

1 Like

I would greatly appreciate it if you could test it for me as I am uncertain whether I could do it properly. I think have both booleans would make more sense, but as far as I can recall, I have not seen it in practice anywhere.

1 Like

Yeah, actually it’s really easy for me to test it

This is what happens if I don’t provide the key to my proxy


Or if I send a request that my proxy doesn’t know what to do with

In contrast to a valid request (here, a ping request, which my proxy is programmed to return “pong”)

Code I used, added comments from yours
local HttpService = game:GetService("HttpService")

local function asyncCall(): boolean
	local success1: boolean = false

	local success2: boolean, message: string = pcall(function()
		local response = HttpService:RequestAsync {
			-- Not leaking my proxy address and stuff
		}
		
		print(response)
		success1 = response.Success

		if not success1 then
			print("The response returned an error:", response.StatusCode, response.StatusMessage)
		end
	end)

	if not success2 then
		print("The Http request failed to send:", message)
	end
	
	print("success1: "..tostring(success1))
	print("success2: "..tostring(success2))
	return success1 and success2
end

print(asyncCall())

Note that in my original reply, I mixed up success1 and success2


RequestAsync can fail if the request body is not set properly, if it the url you are trying to reach doesn’t exit, stuff like that

1 Like

Thank you so much, this is really useful.

In the first two examples, success1 is false while success2 is true. Do you think the other way (success1 == true and success2 == false) is a possible scenario?

To be more specific on what I am doing, I am sending a GET request and setting a variable outside of the function to response.Body. I want to only set this variable when response.Body is valid and retry until a successful response is received.

1 Like

No. If success2 is false, success1 can never be set because a response will never be received. A typical way of structuring such code makes this behaviour very clear

local function asyncCall(): boolean

	local success: boolean, result: string|{[any] : any} = pcall(function()
		local response = HttpService:RequestAsync {
			-- stuff here
		}
		
		return response
	end)

	if not success then
		print("The Http request failed to send:", result)
		return false
	end
	
	local response = result -- Result is the error message in case of an error, or it's whatever the function returned in case of success
	
	if not response.Success then 
		print("The response returned an error:", response.StatusCode, response.StatusMessage)
		return false
	end
	
	return true
end
1 Like

Thank you. If my understanding is correct, since the scenario where pcall success is true and response.Success is false cannot occur, I could disregard pcall success entirely and completely rely on response.Success? The following code should explain what I mean.

local body

local function setBody(): boolean
    local success: boolean = false
    local attemptsRemaining: number = 10
    
    repeat
        attemptsRemaining -= 1
        
        pcall(function() -- success boolean is not needed?
            local response = HttpService:RequestAsync {
                -- cool stuff here
            }

            success = response.Success

            if success then
                body = response.Body
            end
        end)
    until success or attemptsRemaining <= 0
    
    return success
end
1 Like

It’s the opposite, pcall success false and response.Success true is impossible because response is never even defined if pcall success is false

The code you provided would indeed work, because the pcall erroring means the line where success is set to true (or false) hasn’t been reached

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.