Make DataStore 'Service Unavailable' NOT Break The Script

I just encountered an error with a game I’m making where the game (server) was broken because DataStore returned ‘Service Unavailable’ (All I did was store it in a variable).

pcall?

I’m doing that now.
But my point is our script shouldn’t break due to an error on ROBLOX’s end.

not to mention this error means data wasn’t updated to datastore causing problems in many cases. And it is on Roblox’s end.

Is there a difference using pcall or ypcall? Never got around distinguishing when to use either two

Is there a difference using pcall or ypcall? Never got around distinguishing when to use either two[/quote]

pcall doesn’t break the script on errors but also doesn’t yield if there is a hold. ypcall yields and doesn’t break on errors; just always use ypcall whether or not you care that it yields

Is there a difference using pcall or ypcall? Never got around distinguishing when to use either two[/quote]

pcall doesn’t break the script on errors but also doesn’t yield if there is a hold. ypcall yields and doesn’t break on errors; just always use ypcall whether or not you care that it yields[/quote]

Correct me if I’m wrong, but I’ve also noticed a significant performance hit when using ypcall over pcall.

[quote]
Correct me if I’m wrong, but I’ve also noticed a significant performance hit when using ypcall over pcall. [/quote]

We just need a way for scripts to ignore errors.

Ahhhh fudge. I just realized that I may be skipping a wait() by pcalling… OOOppppsss

@OP I wouldn’t mind having:

DataStore, Success = game:DataStoreServiceotherstuffwhateveryougetthepoint()

I’d rather them fix the “Service Unavailable” error e.e

“Correct me if I’m wrong, but I’ve also noticed a significant performance hit when using ypcall over pcall.”

You would be wrong because we changed it a while back so that pcall is just an alias for ypcall, the perf difference wasn’t enough to justify having two separate functions. So, it’s all in your imagination, try it for yourself:
pcall(function() wait(1) print(“A”) end)

Is there a difference using pcall or ypcall? Never got around distinguishing when to use either two[/quote]

As far as I know, ypcall allows to yield (yield protected call) (wait). So a wait wouldn’t work with pcall, but ypcall opposite results assuming all code is correct.

“As far as I know, ypcall allows to yield (yield protected call) (wait). So a wait wouldn’t work with pcall, but ypcall opposite results assuming all code is correct.”

This is normally the correct answer, however, we just aliased pcall to mean exactly the same thing as ypcall on Roblox shortly after adding ypcall, so on Roblox they mean the exact same thing, and waits will work in either.

I don’t understand the suggestion. Obviously you want your scripts to work, but how should they work? What will DSS return if it errors? It can’t return nil - that represents a non-existent value, and what should happen when Set fails? Maybe you want calls to yield until DSS is available again? But that can’t happen because DSS might go offline for maintenance at some point and make your game completely unusable for days.

I think pcall is the best fix here. Everyone is going to do different things with their data, so only you know what should be done when DSS is unavailable. I think you can handle that on your own.


Roblox might be able to fix this but that won’t allow you to stop writing escape routes for when it fails. You should always be prepared for web requests to fail. Always. If you aren’t prepared and DSS has to be taken offline due to some serious exploit then your game locks up and falls to pieces, in the best case. In the worst case you’re looking at lost, misplaced, and corrupted data as a result of assorted failures. You absolutely need to have some escape route for when it fails, so roblox fixing these errors won’t actually solve anything if you’re worried about your code’s complexity.

“What will DSS return if it errors?”

Ideally it would return something in the form: GetAsync() → value, Enum.DataStoreStatus.someStatus

The real question is whether DataStore failure is an exceptional scenario or not. If you expect failure during normal operation, there should be a status code of some sort to represent it. On the other hand, if you’re saying, “no, it should never fail”, but in some very rare scenarios it might, then catching the failure with pcall is the right solution, since that’s what pcall is for: scenarios where “it shouldn’t fail”, but you pcall “just in case it does fail somehow”.

I’m confused on the status of this discussion.

I seem to have lost playerdata on my game (I use DataStore) and I don’t have a good error logging (Google/Roblox analytics doesn’t let you see past errors?). Is this ‘Service Unavailable’ still a real issue or is it just some rare thing or what?

It’s still an issue, I’ll get it in about every other server of my game. good thing my game doesn’t save data. I use it more to communicate between servers.

Well shoot. How am I supposed to save and load PlayerData if the service is broken? :angry:

you could wrap the Save call in a pcall like so:

while not pcall(function() UpdateAsync(“Key”,Data) end) do wait(60) end

so like if a player leaves the server and his data failed to save, then every minute it will try again until either the service is available or the server shuts down. So still a chance to lose data but only if your like the last one in the game.

Being the last one ingame is a common ocurance :stuck_out_tongue: But your code is still useful;[strike] I’ll try it.[/strike] Thanks!

function handleFailure( func, ... ) while not pcall(function() func(...) end) do wait(60) end end --other code handleFailure(ResourceStore:SetAsync, oldPlayer.userId, oldResourceData)

That’ll work; right?

EDIT: That solution won’t work for me. If the player teleports to another server and their resources didn’t save yet they’d load the old ones. Eventually the first server will upload but it won’t matter because the new server will overwrite the data. :confused: