mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 05:51:39 +00:00
Enhance StdBackend with critical error handling and improve file watcher reliability
- Introduced `WatcherCriticalError` enum to categorize critical errors from the file watcher. - Added a `CriticalErrorHandler` callback type for custom error handling in the watcher thread. - Updated `StdBackend` to include a receiver for critical errors, allowing for better error management and logging. - Refactored the watcher thread to handle errors gracefully instead of terminating the process, improving overall stability.
This commit is contained in:
parent
78aab0eca4
commit
41363473b2
27 changed files with 409 additions and 173 deletions
|
|
@ -56,7 +56,8 @@ local function SelectionOption(props)
|
|||
return Theme.with(function(theme)
|
||||
local isSelected = props.isSelected
|
||||
local bgColor = if isSelected
|
||||
then (if props.optionType == "push" then Color3.fromHex("27AE60")
|
||||
then (if props.optionType == "push"
|
||||
then Color3.fromHex("27AE60")
|
||||
elseif props.optionType == "pull" then Color3.fromHex("E74C3C")
|
||||
else Color3.fromHex("7F8C8D"))
|
||||
else theme.BorderedContainer.BackgroundColor
|
||||
|
|
|
|||
|
|
@ -130,19 +130,27 @@ function TextButton:render()
|
|||
zIndex = -1,
|
||||
}),
|
||||
|
||||
Background = (style == "Solid" or style == "Warning" or style == "Primary" or style == "Success" or style == "Danger" or style == "Neutral") and e(SlicedImage, {
|
||||
slice = Assets.Slices.RoundedBackground,
|
||||
color = bindingUtil.mapLerp(
|
||||
bindingEnabled,
|
||||
buttonTheme.Enabled.BackgroundColor,
|
||||
buttonTheme.Disabled.BackgroundColor
|
||||
),
|
||||
transparency = self.props.transparency,
|
||||
Background = (
|
||||
style == "Solid"
|
||||
or style == "Warning"
|
||||
or style == "Primary"
|
||||
or style == "Success"
|
||||
or style == "Danger"
|
||||
or style == "Neutral"
|
||||
)
|
||||
and e(SlicedImage, {
|
||||
slice = Assets.Slices.RoundedBackground,
|
||||
color = bindingUtil.mapLerp(
|
||||
bindingEnabled,
|
||||
buttonTheme.Enabled.BackgroundColor,
|
||||
buttonTheme.Disabled.BackgroundColor
|
||||
),
|
||||
transparency = self.props.transparency,
|
||||
|
||||
size = UDim2.new(1, 0, 1, 0),
|
||||
size = UDim2.new(1, 0, 1, 0),
|
||||
|
||||
zIndex = -2,
|
||||
}),
|
||||
zIndex = -2,
|
||||
}),
|
||||
|
||||
Children = Roact.createFragment(self.props[Roact.Children]),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -125,13 +125,13 @@ function ConfirmingPage:render()
|
|||
LayoutOrder = 4,
|
||||
BackgroundTransparency = 1,
|
||||
}, {
|
||||
Abort = e(TextButton, {
|
||||
text = "Abort",
|
||||
style = "Bordered",
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 1,
|
||||
onClick = self.props.onAbort,
|
||||
}),
|
||||
Abort = e(TextButton, {
|
||||
text = "Abort",
|
||||
style = "Bordered",
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 1,
|
||||
onClick = self.props.onAbort,
|
||||
}),
|
||||
|
||||
PullAll = if Settings:get("twoWaySync")
|
||||
then e(TextButton, {
|
||||
|
|
@ -274,8 +274,7 @@ function ConfirmingPage:render()
|
|||
}),
|
||||
}),
|
||||
}),
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
if self.props.createPopup then
|
||||
return e(StudioPluginGui, {
|
||||
|
|
|
|||
|
|
@ -803,6 +803,23 @@ function App:startSession()
|
|||
-- Track if this was the initial sync for this project
|
||||
local isInitialSyncForProject = not self.knownProjects[serverInfo.projectName]
|
||||
|
||||
-- One-shot sync: disconnect immediately after confirmation
|
||||
-- Skip the "Connected" UI state entirely to avoid flash
|
||||
if Settings:get("oneShotSync") then
|
||||
local resultType = if type(result) == "table" then result.type else result
|
||||
if resultType == "Confirm" or resultType == "Accept" then
|
||||
-- Use task.defer to disconnect after patch is applied (runs after current thread yields)
|
||||
task.defer(function()
|
||||
if self.serveSession then
|
||||
Log.info("One-shot sync: disconnecting after sync")
|
||||
self:endSession()
|
||||
end
|
||||
end)
|
||||
end
|
||||
-- Don't transition to Connected UI, just return result and let disconnect happen
|
||||
return result
|
||||
end
|
||||
|
||||
-- Reset UI state back to Connected after confirmation
|
||||
-- This is needed for ongoing WebSocket patches where the session
|
||||
-- is already connected and won't trigger a status change
|
||||
|
|
@ -816,20 +833,6 @@ function App:startSession()
|
|||
})
|
||||
end
|
||||
|
||||
-- One-shot sync: disconnect after confirmation
|
||||
if Settings:get("oneShotSync") then
|
||||
local resultType = if type(result) == "table" then result.type else result
|
||||
if resultType == "Confirm" or resultType == "Accept" then
|
||||
-- Delay slightly to allow patch to be applied
|
||||
task.delay(0.5, function()
|
||||
if self.serveSession then
|
||||
Log.info("One-shot sync: disconnecting after sync")
|
||||
self:endSession()
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end)
|
||||
|
||||
|
|
|
|||
|
|
@ -290,15 +290,17 @@ function ServeSession:start()
|
|||
-- during confirmation can be merged into the patch
|
||||
-- Note: connectWebSocket returns a Promise that only resolves when
|
||||
-- the connection closes, so we don't chain .andThen() on it
|
||||
self.__apiContext:connectWebSocket({
|
||||
["messages"] = function(messagesPacket)
|
||||
self:__onWebSocketMessage(messagesPacket)
|
||||
end,
|
||||
}):catch(function(err)
|
||||
if self.__status ~= Status.Disconnected then
|
||||
self:__stopInternal(err)
|
||||
end
|
||||
end)
|
||||
self.__apiContext
|
||||
:connectWebSocket({
|
||||
["messages"] = function(messagesPacket)
|
||||
self:__onWebSocketMessage(messagesPacket)
|
||||
end,
|
||||
})
|
||||
:catch(function(err)
|
||||
if self.__status ~= Status.Disconnected then
|
||||
self:__stopInternal(err)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Now show confirmation and wait for user decision
|
||||
return self:__confirmAndApplyInitialPatch(catchUpPatch, serverInfo)
|
||||
|
|
@ -649,7 +651,9 @@ function ServeSession:__confirmAndApplyInitialPatch(catchUpPatch, serverInfo)
|
|||
|
||||
-- Process removed items
|
||||
for _, idOrInstance in catchUpPatch.removed do
|
||||
local id = if type(idOrInstance) == "string" then idOrInstance else self.__instanceMap.fromInstances[idOrInstance]
|
||||
local id = if type(idOrInstance) == "string"
|
||||
then idOrInstance
|
||||
else self.__instanceMap.fromInstances[idOrInstance]
|
||||
local selection = selections[id]
|
||||
if selection == "push" then
|
||||
-- Apply Rojo removal to Studio
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue