@@ -190,11 +190,7 @@ propLockstep_ModelIOImpl =
190
190
env :: RealEnv ModelIO. Table IO
191
191
env = RealEnv {
192
192
envSession = session
193
- , envHandlers = [
194
- handler
195
- , fileFormatErrorHandler
196
- , diskFaultErrorHandler
197
- ]
193
+ , envHandlers = [handler]
198
194
, envErrors = errsVar
199
195
, envInjectFaultResults = faultsVar
200
196
}
@@ -295,11 +291,7 @@ propLockstep_RealImpl_RealFS_IO tr =
295
291
env :: RealEnv R. Table IO
296
292
env = RealEnv {
297
293
envSession = session
298
- , envHandlers = [
299
- realHandler @ IO
300
- , fileFormatErrorHandler
301
- , diskFaultErrorHandler
302
- ]
294
+ , envHandlers = realErrorHandlers @ IO
303
295
, envErrors = errsVar
304
296
, envInjectFaultResults = faultsVar
305
297
}
@@ -338,11 +330,7 @@ propLockstep_RealImpl_MockFS_IO tr =
338
330
env :: RealEnv R. Table IO
339
331
env = RealEnv {
340
332
envSession = session
341
- , envHandlers = [
342
- realHandler @ IO
343
- , fileFormatErrorHandler
344
- , diskFaultErrorHandler
345
- ]
333
+ , envHandlers = realErrorHandlers @ IO
346
334
, envErrors = errsVar
347
335
, envInjectFaultResults = faultsVar
348
336
}
@@ -375,11 +363,7 @@ propLockstep_RealImpl_MockFS_IOSim tr actions =
375
363
env :: RealEnv R. Table (IOSim s )
376
364
env = RealEnv {
377
365
envSession = session
378
- , envHandlers = [
379
- realHandler @ (IOSim s )
380
- , fileFormatErrorHandler
381
- , diskFaultErrorHandler
382
- ]
366
+ , envHandlers = realErrorHandlers @ (IOSim s )
383
367
, envErrors = errsVar
384
368
, envInjectFaultResults = faultsVar
385
369
}
@@ -439,8 +423,30 @@ getAllSessionCursors (R.Internal.Session' s) =
439
423
cs <- readMVar (R.Internal. sessionOpenCursors seshEnv)
440
424
pure ((\ x -> SomeCursor (R.Internal. Cursor' x)) <$> Map. elems cs)
441
425
442
- realHandler :: Monad m => Handler m (Maybe Model. Err )
443
- realHandler = Handler $ pure . handler'
426
+ createSystemTempDirectory :: [Char ] -> IO (FilePath , HasFS IO HandleIO , HasBlockIO IO HandleIO )
427
+ createSystemTempDirectory prefix = do
428
+ systemTempDir <- getCanonicalTemporaryDirectory
429
+ tempDir <- createTempDirectory systemTempDir prefix
430
+ let hasFS = ioHasFS (MountPoint tempDir)
431
+ hasBlockIO <- ioHasBlockIO hasFS defaultIOCtxParams
432
+ pure (tempDir, hasFS, hasBlockIO)
433
+
434
+ {- ------------------------------------------------------------------------------
435
+ Error handlers
436
+ -------------------------------------------------------------------------------}
437
+
438
+ realErrorHandlers :: Monad m => [Handler m (Maybe Model. Err )]
439
+ realErrorHandlers = [
440
+ lsmTreeErrorHandler
441
+ , commitActionRegistryErrorHandler
442
+ , abortActionRegistryErrorHandler
443
+ , fsErrorHandler
444
+ , fileFormatErrorHandler
445
+ , catchAllErrorHandler
446
+ ]
447
+
448
+ lsmTreeErrorHandler :: Monad m => Handler m (Maybe Model. Err )
449
+ lsmTreeErrorHandler = Handler $ pure . handler'
444
450
where
445
451
handler' :: LSMTreeError -> Maybe Model. Err
446
452
handler' ErrTableClosed = Just Model. ErrTableClosed
@@ -449,48 +455,65 @@ realHandler = Handler $ pure . handler'
449
455
handler' (ErrSnapshotExists _snap) = Just Model. ErrSnapshotExists
450
456
handler' ErrSnapshotWrongTableType {} = Just Model. ErrSnapshotWrongType
451
457
handler' (ErrBlobRefInvalid _) = Just Model. ErrBlobRefInvalidated
452
- handler' _ = Nothing
458
+ handler' e = Just ( Model. ErrOther (displayException e))
453
459
454
- -- | When combined with other handlers, 'diskFaultErrorHandler' has to go last
455
- -- because it matches on 'SomeException', an no other handlers are run after
456
- -- that. See the use of 'catches' in 'catchErr'.
457
- diskFaultErrorHandler :: Monad m => Handler m (Maybe Model. Err )
458
- diskFaultErrorHandler = Handler $ \ e -> pure $
459
- if isDiskFault e
460
- then Just (Model. ErrDiskFault (displayException e))
461
- else Nothing
460
+ commitActionRegistryErrorHandler :: Monad m => Handler m (Maybe Model. Err )
461
+ commitActionRegistryErrorHandler = Handler $ pure . handler'
462
+ where
463
+ handler' :: CommitActionRegistryError -> Maybe Model. Err
464
+ handler' e
465
+ | isDiskFault (toException e) = Just (Model. ErrDiskFault (displayException e))
466
+ | otherwise = Just (Model. ErrOther (displayException e))
462
467
468
+ abortActionRegistryErrorHandler :: Monad m => Handler m (Maybe Model. Err )
469
+ abortActionRegistryErrorHandler = Handler $ pure . handler'
470
+ where
471
+ handler' :: AbortActionRegistryError -> Maybe Model. Err
472
+ handler' e
473
+ | isDiskFault (toException e) = Just (Model. ErrDiskFault (displayException e))
474
+ | otherwise = Just (Model. ErrOther (displayException e))
475
+
476
+ -- | Some exceptions contain other exceptions. We check recursively if there is
477
+ -- *any* exception that must have occurred because of a disk fault, and if so we
478
+ -- consider the whole structure of exceptions a disk fault exception.
463
479
isDiskFault :: SomeException -> Bool
464
480
isDiskFault e
465
481
| Just (CommitActionRegistryError es) <- fromException e
466
- = all isDiskFault' es
482
+ = any isDiskFault' es
467
483
| Just (AbortActionRegistryError reason es) <- fromException e
468
484
= case reason of
469
- ReasonExitCaseException e' -> isDiskFault e' && all isDiskFault' es
485
+ ReasonExitCaseException e' -> isDiskFault e' || any isDiskFault' es
470
486
ReasonExitCaseAbort -> False
471
487
| Just (e' :: ActionError ) <- fromException e
472
488
= isDiskFault' (getActionError e')
473
489
| Just FsError {} <- fromException e
474
490
= True
491
+ | Just FileFormatError {} <- fromException e
492
+ = True
475
493
| otherwise
476
494
= False
477
495
where
478
496
isDiskFault' :: forall e . Exception e => e -> Bool
479
497
isDiskFault' = isDiskFault . toException
480
498
499
+ fsErrorHandler :: Monad m => Handler m (Maybe Model. Err )
500
+ fsErrorHandler = Handler $ pure . handler'
501
+ where
502
+ handler' :: FsError -> Maybe Model. Err
503
+ handler' e = Just (Model. ErrDiskFault (displayException e))
504
+
481
505
fileFormatErrorHandler :: Monad m => Handler m (Maybe Model. Err )
482
506
fileFormatErrorHandler = Handler $ pure . handler'
483
507
where
484
508
handler' :: FileFormatError -> Maybe Model. Err
485
509
handler' e = Just (Model. ErrDiskFault (displayException e))
486
510
487
- createSystemTempDirectory :: [Char ] -> IO (FilePath , HasFS IO HandleIO , HasBlockIO IO HandleIO )
488
- createSystemTempDirectory prefix = do
489
- systemTempDir <- getCanonicalTemporaryDirectory
490
- tempDir <- createTempDirectory systemTempDir prefix
491
- let hasFS = ioHasFS (MountPoint tempDir)
492
- hasBlockIO <- ioHasBlockIO hasFS defaultIOCtxParams
493
- pure (tempDir, hasFS, hasBlockIO)
511
+ -- | When combined with other handlers, 'catchAllErrorHandler' has to go last
512
+ -- because it matches on 'SomeException', an no other handlers are run after
513
+ -- that. See the use of 'catches' in 'catchErr'.
514
+ catchAllErrorHandler :: Monad m => Handler m (Maybe Model. Err )
515
+ catchAllErrorHandler = Handler $ \ (e :: SomeException ) ->
516
+ pure $ Just (Model. ErrOther (displayException e))
494
517
495
518
{- ------------------------------------------------------------------------------
496
519
Key and value types
0 commit comments