How can I keep my data from saving if pcall fails?

Interesting. I can see what you’re saying.

The data is saving before the error is called, but then when the error is called, the data fails.

Can you tell me what the says in the output?

The output is printing out the last number saved from the final line:

print(_DATASTORE_SEVER:GetAsync("TEST"))

Even though the pcall is failing

Ah, yes. This makes so much sense now!

The data is in the process of saving, but then the error is called when there are too many Data Requests sent. When too much Requests are sent, the data fails to save before it finishes.

In other words, you’re gonna have to fix the error. I don’t think its possible to save the data after the error is called.

Well this is my fix to fixing the request issue:

coroutine.wrap(function()
  _DATASTORE_SEVER:SetAsync("TEST", math.random(1,15))
end)

Then it would still work the same as before?

Because now, with my code like this:

local _DATASTORE_SEVER = game:GetService("DataStoreService"):GetDataStore("____SEERRRVVVEEREEEERR_DDDAAAATTTTAAAAAAA_______")

for i = 1, 5 do
	task.wait(2)
	local Save__DATA, _message = pcall(function()
		coroutine.wrap(function()
			_DATASTORE_SEVER:SetAsync("TEST", math.random(1,15))
		end)
		game.Workspaaaceee = 3 --ERROR (on purpose.)
		--Keep the data from saving due to this error.
	end)

	if Save__DATA == true then
		print("Saved", i)
	else
		warn(_message)
	end

	print(_DATASTORE_SEVER:GetAsync("TEST"))
end

My data will not change at all.

Even if I get rid of the error part:

game.Workspaaaceee = 3 --ERROR (on purpose.)


?

This does not work either

local _DATASTORE_SEVER = game:GetService("DataStoreService"):GetDataStore("____SEERRRVVVEEREEEERR_DDDAAAATTTTAAAAAAA_______")

for i = 1, 5 do
	task.wait(2)
	local Save__DATA, _message = pcall(function()
		local save = coroutine.wrap(function()
		
			_DATASTORE_SEVER:SetAsync("TEST", math.random(1,15))
		end)
		
		save()
		game.Workspaaaceee = 3 --ERROR (on purpose.)
		--Keep the data from saving due to this error.
	end)

	if Save__DATA == true then
		print("Saved", i)
	else
		warn(_message)
	end

	print(_DATASTORE_SEVER:GetAsync("TEST"))
end

still need help.ㅤㅤ
ㅤㅤ
ㅤㅤ
ㅤㅤ
ㅤㅤ
ㅤㅤ

The pcall means at all a “protected call”, it lets you run a task that can have a success or you can catch an error within, if the function errors, what do you expect? It won’t save.

In addition to the stated above, you may be doing something else wrong if you got rid of the error and still got no data change at all.

Also, it doesn’t make sense you’re doing this within a loop, this is why it sends the request to the queue, because you’re sending too many of them. Break the loop once it is saved.

This is happening because the error happens after the saving. the :SetAsync() call succeeds THEN the pcall errors.

To simulate a failing call, you could move the error to before the SetAsync. (By the way, try using the builtin error() function instead.

But besides all of this, SetAsync has been prone to data loss because it has no handling, so if you pass in nil, it just completely clears the player’s data. I’d recommend using some of the many, many datastore modules that take care of the messy saving process automatically (I use ProfileService, because it’s super good at preventing data loss and easy to use once you understand it).

Well you see, I wanted to originally use profileService for this but I couldn’t figure out how to save data on my game/server (NOT FOR THE PLAYER) AND update / send updates across servers without profile service automatically releasing my data and not holding onto my data when I need too. IF you’d like to help me out with that then yes, pls dm me.

local _DATASTORE_SEVER = game:GetService("DataStoreService"):GetDataStore("____SEERRRVVVEEREEEERR_DDDAAAATTTTAAAAAAA_______")

for i = 1, 5 do
	task.wait(5)
	coroutine.wrap(function()
		local Save__DATA, _message
		Save__DATA, _message = pcall(function()
			_DATASTORE_SEVER:SetAsync("TEST", math.random(1,15))
			game.Workspaaaceee = 3 --the script will stop running because of this error
		end)
		if Save__DATA == true then
			print("Saved", i)
		else
			warn(_message)
		end
		print(_DATASTORE_SEVER:GetAsync("TEST"))
	end)
end

still no good.

local _DATASTORE_SEVER = game:GetService("DataStoreService"):GetDataStore("____SEERRRVVVEEREEEERR_DDDAAAATTTTAAAAAAA_______")

for i = 1, 5 do
	print(1)
	task.wait(60)
	local save = coroutine.wrap(function()
		print(2)
		local Save__DATA, _message
		Save__DATA, _message = pcall(function()
			_DATASTORE_SEVER:SetAsync("TEST", math.random(1,15))
			game.Workspaaaceee = 3 --the script will stop running because of this error
		end)
		if Save__DATA == true then
			print("Saved", i)
		else
			warn(_message)
		end
		print(_DATASTORE_SEVER:GetAsync("TEST"))
	end)
	save()
end

Would it be possible to get an example of having 2 saves so that it could possibly revert back to the old save if the function fails?

All I want is for my data to NOT SAVE if the pcall fails.

Sorry if I didn’t understand it at all, but from the very first start, why would your pcall fail? You should only be trying to save data within, if the request fails, then the save isn’t performed. :thinking:

Example:

local function func(oldValue)
    return ... -- new value to save
end

local success, name, keyInfo = pcall(function()
    return GlobalDataStore:UpdateAsync(key, func)
end)

if not success then
    warn("Something went wrong!")
else
    print("Version: " .. keyInfo.Version)
end

Nothing more, nothing less. The saving of it shouldn’t be interfered or enclosed with anything else, not recommended.

Use UpdateAsync and place all the code that can error in it. It’s more reliable than SetAsync and will only update the data once you return a value that isn’t nil.

As an added bonus, it parses the previously saved value. This way you can modify that value and even compare it to the currently present data to check if you want to keep it or not.

If the save actually fails, then the data won’t be updated. If you aren’t doing some random error like game.Worrrsspace = 1, then you will know by if the pcall is successful or not if it saved or not.
You will know if it saved by if the pcall is successful or not, as long as you don’t do a weird error inside the pcall.
Here’s an example of having a backup save:

local function saveData(key, val)
  local success, em = pcall(function()
    dataStore:SetAsync(key.."1", val)
  end)
  if not success then print(em); return end
  success, em = pcall(function()
    dataStore:SetAsync(key.."2", val)
  end)
  if not success then print(em); return end
  return true
end

He’s purposefully erroring the function wrapped inside the pcall() call after :UpdateAsync() has been called.

I’m not sure why though, :UpdateAsync() won’t update any data if it errors itself.

If your pcall failed and it wasn’t due to SetAsync, then what the hell would be failing?

If your intention is to call a function that returns whatever it needs to as the second parameter for SetAsync, just… pcall that function before the SetAsync… And then check if that pcall failed separately before doing SetAsync().

Otherwise, what your trying to do isn’t possible and your explanation is nonsensical.