Skip to content

Commit bd9f02c

Browse files
committed
fix(web): raise 409 on duplicate pane creation
Because both the C display server and Haskell web server layers maintain independent registries of panes (the former to map them to display information and the latter to map them to auth tokens), it's kind of tricky to check the implicit invariant that there never exists an entry in one that isn't in the other. You might think that there would be a way to atomically check that the pane doesn't exist in the C layer before adding it to the Haskell layer, but that would require doing IO inside an STM transaction, which is widely considered to be a bad idea. Instead, we do something moderately hacky, i.e., we just match on the error message. Fixes #53.
1 parent 48caaca commit bd9f02c

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

web/app/Main.hs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import qualified Data.Text as T
1010
import Data.Text.Lazy (pack, toStrict)
1111
import Data.UUID (toText)
1212
import GHC.Conc (atomically)
13-
import Network.HTTP.Types.Status (badRequest400, unauthorized401)
13+
import Network.HTTP.Types.Status (badRequest400, unauthorized401, conflict409, internalServerError500)
1414
import Proc (Proc, call, kill, launch, mkCommand, mkUnvalidatedCommand, mkComp)
1515
import System.Environment (getArgs)
1616
import System.Posix.Signals (Handler (..), installHandler, sigINT)
@@ -81,7 +81,10 @@ runWebServer proc ts =
8181

8282
callCmd cmd = callAct cmd >>= \case
8383
"OK" -> return ()
84-
x -> (text . pack) x >> finish
84+
x -> setStatusFromErr x >> (text . pack) x >> finish
85+
86+
setStatusFromErr "act_create: failed: duplicate pane" = status conflict409
87+
setStatusFromErr x = status internalServerError500
8588

8689
requireAdmin :: TokenStore -> ActionM ()
8790
requireAdmin ts = header "Auth" >>= isOk >>= verify

0 commit comments

Comments
 (0)