diff --git a/src/discordas.ts b/src/discordas.ts
index 01b69d73ce199311860eddded7f016f93fd3b40a..2ddbe5f614b40db7101e04f7fc8c7a8ec4fc620b 100644
--- a/src/discordas.ts
+++ b/src/discordas.ts
@@ -20,6 +20,7 @@ import {
     BridgeContext,
     Cli,
     ClientFactory,
+    default_message,
     thirdPartyLookup,
 } from "matrix-appservice-bridge";
 import * as yaml from "js-yaml";
@@ -115,30 +116,22 @@ async function run(port: number, fileConfig: DiscordBridgeConfig) {
             onEvent: async (request) => {
                 const data = request.getData();
                 try {
-                    MetricPeg.get.registerRequest(data.event_id);
-                    // Build our own context.
-                    if (!store.roomStore) {
-                        log.warn("Discord store not ready yet, dropping message");
-                        MetricPeg.get.requestOutcome(data.event_id, false, "dropped");
-                        return;
-                    }
                     const roomId = data.room_id;
+                    MetricPeg.get.registerRequest(data.event_id);
 
-                    const context: BridgeContext = {
-                        rooms: {},
-                    };
-
-                    if (roomId) {
-                        const entries  = await store.roomStore.getEntriesByMatrixId(roomId);
-                        context.rooms = entries[0] || {};
-                    }
-
-                    await request.outcomeFrom(callbacks.onEvent(request, context));
+                    const context = await buildOwnContext(roomId, store);
+                    const callback = callbacks.onEvent(request, context);
+                    request.outcomeFrom(callback);
                     MetricPeg.get.requestOutcome(data.event_id, false, "success");
                 } catch (err) {
-                    MetricPeg.get.requestOutcome(data.event_id, false, "fail");
-                    log.error("Exception thrown while handling \"onEvent\" event", err);
-                    await request.outcomeFrom(Promise.reject("Failed to handle"));
+                    if (err instanceof NotReadyError) {
+                        log.warn("Discord store not ready yet, dropping message");
+                        MetricPeg.get.requestOutcome(data.event_id, false, "dropped");
+                    } else {
+                        MetricPeg.get.requestOutcome(data.event_id, false, "fail");
+                        log.error("Exception thrown while handling \"onEvent\" event", err);
+                        await request.outcomeFrom(Promise.reject("Failed to handle"));
+                    }
                 }
             },
             onLog: (line, isError) => {
@@ -229,3 +222,33 @@ async function run(port: number, fileConfig: DiscordBridgeConfig) {
         process.exit(1);
     }
 }
+
+/**
+ * Builds a custom BridgeContext with rooms known to the bridge.
+ */
+async function buildOwnContext(
+    roomId: string,
+    store: DiscordStore,
+): Promise<BridgeContext> {
+    if (!store.roomStore) {
+        throw new NotReadyError("Discord store not ready yet, will retry later");
+    }
+
+    const entries = await store.roomStore.getEntriesByMatrixId(roomId);
+
+    return {
+        rooms: entries[0] || {},
+        senders: {},
+        targets: {},
+    };
+}
+
+class NotReadyError extends Error {
+    public name: string;
+
+    constructor(...params) {
+        default_message(params, "The bridge was not ready when the message was sent");
+        super(...params);
+        this.name = "NotReadyError";
+    }
+}