You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For the JS/PY/R runtimes, processProgram correctly sets session.state = SessionState.failed (with session.failureReason set)
when the spawned interpreter process exits non-zero:
Unlike the SAS runtime, this branch doesn't throw on failure — it just sets
the state and returns normally. Immediately after processProgram returns, ExecutionController.executeProgram unconditionally overwrites that state:
// it should be deleted by scheduleSessionDestroysession.state=SessionState.completed
So a JS/PY/R session that just failed has its failed state silently
stomped back to completed before the session is ever cleaned up or
reused.
Impact
session.failureReason is still returned correctly in the HTTP response
(that's read from the log/webout files, not from session.state), so this does not affect the client-visible error response for a single
request.
The impact is on the session object's own bookkeeping: anything that
later inspects session.state (e.g. scheduleSessionDestroy in Session.ts:204-236, which branches on state !== SessionState.completed
for expiresAfterMins handling) sees a crashed session mis-reported as
successfully completed.
Found as a related-but-out-of-scope finding while investigating #388
("Stored Programs fail to respond in API when SAS errors"). Not fixed
there to keep that PR scoped to the SAS hang; tracked here as a follow-up.
Description
For the JS/PY/R runtimes,
processProgramcorrectly setssession.state = SessionState.failed(withsession.failureReasonset)when the spawned interpreter process exits non-zero:
https://github.com/sasjs/server/blob/0af6b63/api/src/controllers/internal/processProgram.ts#L121-L131
Unlike the SAS runtime, this branch doesn't throw on failure — it just sets
the state and returns normally. Immediately after
processProgramreturns,ExecutionController.executeProgramunconditionally overwrites that state:https://github.com/sasjs/server/blob/0af6b63/api/src/controllers/internal/Execution.ts#L146-L147
So a JS/PY/R session that just failed has its
failedstate silentlystomped back to
completedbefore the session is ever cleaned up orreused.
Impact
session.failureReasonis still returned correctly in the HTTP response(that's read from the log/webout files, not from
session.state), sothis does not affect the client-visible error response for a single
request.
later inspects
session.state(e.g.scheduleSessionDestroyinSession.ts:204-236, which branches onstate !== SessionState.completedfor
expiresAfterMinshandling) sees a crashed session mis-reported assuccessfully completed.
since Stored Programs fail to respond in API when SAS errors #388's fix, a failed SAS session throws out of
processProgrambefore
Execution.ts:147is ever reached.Suggested fix
Only set
completedif the session didn't already fail, e.g.:Context
Found as a related-but-out-of-scope finding while investigating #388
("Stored Programs fail to respond in API when SAS errors"). Not fixed
there to keep that PR scoped to the SAS hang; tracked here as a follow-up.