diff --git a/src/Quasar/Awaitable.hs b/src/Quasar/Awaitable.hs
index ddbd64978f2516883f1fb94e9000a7ad5bfef53c..47dd6b7cdcfe40bd57d4e54806a1a677fcaaed1e 100644
--- a/src/Quasar/Awaitable.hs
+++ b/src/Quasar/Awaitable.hs
@@ -2,6 +2,7 @@ module Quasar.Awaitable (
   -- * MonadAwaitable
   MonadAwait(..),
   peekAwaitable,
+  peekAwaitableSTM,
   awaitSTM,
 
   -- * Awaitable
@@ -105,6 +106,11 @@ instance MonadAwait m => MonadAwait (MaybeT m) where
 peekAwaitable :: MonadIO m => Awaitable r -> m (Maybe r)
 peekAwaitable awaitable = liftIO $ atomically $ (Just <$> awaitSTM awaitable) `orElse` pure Nothing
 
+-- | Returns the result (in a `Just`) when the awaitable is completed, throws an `Exception` when the awaitable is
+-- failed and returns `Nothing` otherwise.
+peekAwaitableSTM :: Awaitable r -> STM (Maybe r)
+peekAwaitableSTM awaitable = (Just <$> awaitSTM awaitable) `orElse` pure Nothing
+
 
 
 class IsAwaitable r a | a -> r where
diff --git a/src/Quasar/Exceptions.hs b/src/Quasar/Exceptions.hs
index 1c2fe456146b8584abbe0fcead114db2efb87f74..572d4847419bed077613f354ae8f6241090c7a89 100644
--- a/src/Quasar/Exceptions.hs
+++ b/src/Quasar/Exceptions.hs
@@ -12,6 +12,10 @@ module Quasar.Exceptions (
   isAsyncDisposed,
   DisposeException(..),
   isDisposeException,
+  FailedToAttachResource(..),
+  isFailedToAttachResource,
+  AlreadyDisposing(..),
+  isAlreadyDisposing,
 ) where
 
 import Control.Concurrent.STM
@@ -62,7 +66,7 @@ isAsyncDisposed (fromException @AsyncDisposed -> Just _) = True
 isAsyncDisposed _ = False
 
 
-  
+
 data DisposeException = DisposeException SomeException
   deriving stock Show
 
@@ -72,3 +76,28 @@ instance Exception DisposeException where
 isDisposeException :: SomeException -> Bool
 isDisposeException (fromException @DisposeException -> Just _) = True
 isDisposeException _ = False
+
+
+
+data FailedToAttachResource = FailedToAttachResource
+  deriving stock (Eq, Show)
+
+instance Exception FailedToAttachResource where
+  displayException FailedToAttachResource =
+    "FailedToRegisterResource: Failed to attach a resource to a resource manager. This might result in leaked resources if left unhandled."
+
+isFailedToAttachResource :: SomeException -> Bool
+isFailedToAttachResource (fromException @FailedToAttachResource -> Just _) = True
+isFailedToAttachResource _ = False
+
+
+data AlreadyDisposing = AlreadyDisposing
+  deriving stock (Eq, Show)
+
+instance Exception AlreadyDisposing where
+  displayException AlreadyDisposing =
+    "AlreadyDisposing: Failed to create a resource because the resource manager it should be attached to is already disposing."
+
+isAlreadyDisposing :: SomeException -> Bool
+isAlreadyDisposing (fromException @AlreadyDisposing -> Just _) = True
+isAlreadyDisposing _ = False
diff --git a/src/Quasar/Resources.hs b/src/Quasar/Resources.hs
index b6c8e73bd62940f1a44af98783e5f55b887a69ff..3bf9dca665227f45d24849b17c89c6217732be3c 100644
--- a/src/Quasar/Resources.hs
+++ b/src/Quasar/Resources.hs
@@ -2,21 +2,28 @@ module Quasar.Resources (
   -- * Resources
   Resource(..),
   dispose,
-  disposeEventuallySTM,
-  disposeEventuallySTM_,
+  isDisposing,
   isDisposed,
 
-  -- * Monadic resource management
+  -- * Resource management in the `Quasar` monad
   registerResource,
+  registerNewResource,
   registerDisposeAction,
   registerDisposeTransaction,
+  disposeEventually,
+  disposeEventually_,
+
+  -- * STM
+  disposeEventuallySTM,
+  disposeEventuallySTM_,
 
-  -- * Disposer
+  -- * Types to implement resources
+  -- ** Disposer
   Disposer,
   newIODisposer,
   newSTMDisposer,
 
-  -- * Resource manager
+  -- ** Resource manager
   ResourceManager,
   newResourceManagerSTM,
   attachResource,
@@ -24,6 +31,8 @@ module Quasar.Resources (
 
 
 import Control.Concurrent.STM
+import Control.Monad.Catch
+import Quasar.Awaitable
 import Quasar.Async.STMHelper
 import Quasar.Exceptions
 import Quasar.Monad
@@ -56,3 +65,27 @@ registerDisposeTransaction fn = do
   exChan <- askExceptionChannel
   rm <- askResourceManager
   runSTM $ attachResource rm =<< newSTMDisposer worker exChan fn
+
+registerNewResource :: forall a m. (Resource a, MonadQuasar m) => m a -> m a
+registerNewResource fn = do
+  rm <- askResourceManager
+  disposing <- isJust <$> runSTM (peekAwaitableSTM (isDisposing rm))
+  -- Bail out before creating the resource _if possible_
+  when disposing $ throwM AlreadyDisposing
+
+  maskIfRequired do
+    resource <- fn
+    registerResource resource `catchAll` \ex -> do
+      -- When the resource cannot be registered (because resource manager is now disposing), destroy it to prevent leaks
+      disposeEventually_ resource
+      case ex of
+        (fromException -> Just FailedToAttachResource) -> throwM AlreadyDisposing
+        _ -> throwM ex
+    pure resource
+
+
+disposeEventually :: (Resource r, MonadQuasar m) => r -> m (Awaitable ())
+disposeEventually res = runSTM $ disposeEventuallySTM res
+
+disposeEventually_ :: (Resource r, MonadQuasar m) => r -> m ()
+disposeEventually_ res = runSTM $ disposeEventuallySTM_ res