fix: prevent duplicate session action requests causing 404s
- Add early return guards in all session action handlers (start, stop, delete, recreate tunnel) - Prevents race conditions where double-clicks or rapid clicks fire duplicate API calls - First delete succeeds, second would 404 because instance is already deleted - Applied to both sessions page and dashboard/home page
This commit is contained in:
@@ -143,6 +143,7 @@ export const HomePage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleStop = async (session: SessionView) => {
|
const handleStop = async (session: SessionView) => {
|
||||||
|
if (actionBusy === session.id) return;
|
||||||
setActionBusy(session.id);
|
setActionBusy(session.id);
|
||||||
try {
|
try {
|
||||||
await stopInstance(session.project_id, session.repository_id, session.id);
|
await stopInstance(session.project_id, session.repository_id, session.id);
|
||||||
@@ -153,6 +154,7 @@ export const HomePage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = async (session: SessionView) => {
|
const handleDelete = async (session: SessionView) => {
|
||||||
|
if (actionBusy === session.id) return;
|
||||||
setActionBusy(session.id);
|
setActionBusy(session.id);
|
||||||
try {
|
try {
|
||||||
await deleteInstance(session.project_id, session.repository_id, session.id);
|
await deleteInstance(session.project_id, session.repository_id, session.id);
|
||||||
@@ -165,6 +167,7 @@ export const HomePage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRecreateTunnel = async (session: SessionView) => {
|
const handleRecreateTunnel = async (session: SessionView) => {
|
||||||
|
if (actionBusy === session.id) return;
|
||||||
setActionBusy(session.id);
|
setActionBusy(session.id);
|
||||||
try {
|
try {
|
||||||
await recreateInstanceTunnel(session.project_id, session.repository_id, session.id);
|
await recreateInstanceTunnel(session.project_id, session.repository_id, session.id);
|
||||||
@@ -175,6 +178,7 @@ export const HomePage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleStart = async (session: SessionView) => {
|
const handleStart = async (session: SessionView) => {
|
||||||
|
if (actionBusy === session.id) return;
|
||||||
setActionBusy(session.id);
|
setActionBusy(session.id);
|
||||||
try {
|
try {
|
||||||
await startInstance(session.project_id, session.repository_id, session.id);
|
await startInstance(session.project_id, session.repository_id, session.id);
|
||||||
|
|||||||
@@ -155,6 +155,7 @@ export const SessionsPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleStop = async (session: Session) => {
|
const handleStop = async (session: Session) => {
|
||||||
|
if (loadingSessionId === session.id) return;
|
||||||
setLoadingSessionId(session.id);
|
setLoadingSessionId(session.id);
|
||||||
try {
|
try {
|
||||||
await stopInstance(session.project_id, session.repository_id, session.id);
|
await stopInstance(session.project_id, session.repository_id, session.id);
|
||||||
@@ -167,6 +168,7 @@ export const SessionsPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = async (session: Session) => {
|
const handleDelete = async (session: Session) => {
|
||||||
|
if (loadingSessionId === session.id) return;
|
||||||
setLoadingSessionId(session.id);
|
setLoadingSessionId(session.id);
|
||||||
try {
|
try {
|
||||||
await deleteInstance(session.project_id, session.repository_id, session.id);
|
await deleteInstance(session.project_id, session.repository_id, session.id);
|
||||||
@@ -190,6 +192,7 @@ export const SessionsPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleForceDelete = async (session: Session) => {
|
const handleForceDelete = async (session: Session) => {
|
||||||
|
if (loadingSessionId === session.id) return;
|
||||||
setLoadingSessionId(session.id);
|
setLoadingSessionId(session.id);
|
||||||
try {
|
try {
|
||||||
await deleteInstance(session.project_id, session.repository_id, session.id, true);
|
await deleteInstance(session.project_id, session.repository_id, session.id, true);
|
||||||
@@ -204,6 +207,7 @@ export const SessionsPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRecreateTunnel = async (session: Session) => {
|
const handleRecreateTunnel = async (session: Session) => {
|
||||||
|
if (loadingSessionId === session.id) return;
|
||||||
setLoadingSessionId(session.id);
|
setLoadingSessionId(session.id);
|
||||||
try {
|
try {
|
||||||
await recreateInstanceTunnel(
|
await recreateInstanceTunnel(
|
||||||
@@ -221,6 +225,7 @@ export const SessionsPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleStart = async (session: Session) => {
|
const handleStart = async (session: Session) => {
|
||||||
|
if (loadingSessionId === session.id) return;
|
||||||
setLoadingSessionId(session.id);
|
setLoadingSessionId(session.id);
|
||||||
try {
|
try {
|
||||||
await startInstance(session.project_id, session.repository_id, session.id);
|
await startInstance(session.project_id, session.repository_id, session.id);
|
||||||
|
|||||||
Reference in New Issue
Block a user