refactor(gateway): drop shared barrel, migrate to granular imports + shared error helpers

- delete src/shared/index.ts fat barrel; point 10 importers at the exact
  module they use (redis-channels, moderation-types, utils/pagination)
- message-capture/types.ts re-exports from shared/moderation-types directly
- shared/errors: add errorMessage() + isTransientStreamError() helpers,
  replacing the repeated err-message and transient-code checks
- drop unused imports flagged by biome

No behavior change. typecheck + lint + 138 tests green.
This commit is contained in:
asepharyana
2026-09-24 14:58:19 +07:00
parent 8743fcc0b5
commit 6bf3b40cc7
13 changed files with 60 additions and 26 deletions
@@ -1,8 +1,5 @@
import { inArray, lt } from "drizzle-orm";
import type {
NodePgDatabase,
NodePgQueryResultHKT,
} from "drizzle-orm/node-postgres";
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
import { createChildLogger } from "@/shared/logger/index";
import { config } from "../shared/config/index.js";
import { getDatabase } from "../shared/database/drizzle.js";
@@ -1,12 +1,12 @@
import type { Client } from "discord.js-selfbot-v13";
import Redis from "ioredis";
import { config } from "../../shared/config/index.js";
import { createChildLogger } from "../../shared/logger/index.js";
import {
BACKEND_COMMAND,
type CommandMessage,
type CommandReply,
} from "../../shared/index.js";
import { createChildLogger } from "../../shared/logger/index.js";
} from "../../shared/redis-channels.js";
import { GuildHandler } from "./guild.handler.js";
import {
type CommandHandlerFn,
@@ -1,6 +1,9 @@
import type { Client } from "discord.js-selfbot-v13";
import type { CommandMessage, CommandReply } from "../../shared/index.js";
import { createChildLogger } from "../../shared/logger/index.js";
import type {
CommandMessage,
CommandReply,
} from "../../shared/redis-channels.js";
// ---------------------------------------------------------------------------
// GuildHandler
@@ -4,7 +4,7 @@ import {
COMMAND_MODERATION_ACTION,
type CommandMessage,
type CommandReply,
} from "../../shared/index.js";
} from "../../shared/redis-channels.js";
import type { GuildHandler } from "./guild.handler.js";
import type { ModerationHandler } from "./moderation.handler.js";
@@ -1,6 +1,9 @@
import type { Client } from "discord.js-selfbot-v13";
import type { CommandMessage, CommandReply } from "../../shared/index.js";
import { createChildLogger } from "../../shared/logger/index.js";
import type {
CommandMessage,
CommandReply,
} from "../../shared/redis-channels.js";
import { messageStore } from "../message-capture/messageStore.js";
// ---------------------------------------------------------------------------
@@ -1,9 +1,12 @@
import Redis from "ioredis";
import type { AttachmentRecord, MessageRecord } from "../../shared/index.js";
import {
type CustomLogger,
createChildLogger,
} from "../../shared/logger/index.js";
import type {
AttachmentRecord,
MessageRecord,
} from "../../shared/moderation-types.js";
import { type DiscordGatewayEvent, EventChannels } from "./eventTypes.js";
export class RedisEventPublisher {
@@ -17,7 +17,7 @@ import {
DISCORD_THREAD_DELETED,
DISCORD_THREAD_UPDATED,
type DiscordGatewayEvent,
} from "../../shared/index.js";
} from "../../shared/redis-channels.js";
export type { DiscordGatewayEvent };
@@ -2,8 +2,11 @@ import { and, desc, eq, inArray, type SQL, sql } from "drizzle-orm";
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
import type * as schema from "../../shared/database/schema.js";
import { messagesTable } from "../../shared/database/schema.js";
import { buildCursorCondition, pageResult } from "../../shared/index.js";
import { createChildLogger, type Logger } from "../../shared/logger/index.js";
import {
buildCursorCondition,
pageResult,
} from "../../shared/utils/pagination.js";
import type {
MessageQuery,
MessageRecord,
@@ -2,8 +2,11 @@ import { and, desc, eq, inArray, type SQL } from "drizzle-orm";
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
import type * as schema from "../../shared/database/schema.js";
import { moderationActionsTable } from "../../shared/database/schema.js";
import { buildCursorCondition, pageResult } from "../../shared/index.js";
import { createChildLogger, type Logger } from "../../shared/logger/index.js";
import {
buildCursorCondition,
pageResult,
} from "../../shared/utils/pagination.js";
import type { EventBroadcaster } from "../event-broadcaster/eventBroadcaster.js";
import type { ModerationAction, PageResult } from "../message-capture/types.js";
@@ -2,8 +2,11 @@ import { and, desc, eq, inArray, type SQL } from "drizzle-orm";
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
import type * as schema from "../../shared/database/schema.js";
import { messageReviewsTable } from "../../shared/database/schema.js";
import { buildCursorCondition, pageResult } from "../../shared/index.js";
import { createChildLogger, type Logger } from "../../shared/logger/index.js";
import {
buildCursorCondition,
pageResult,
} from "../../shared/utils/pagination.js";
import type { MessageReview, PageResult } from "../message-capture/types.js";
// ─── ReviewsDb Class ────────────────────────────────────────────────────────
@@ -2,8 +2,7 @@ import type {
AnalysisQueueStatus,
AttachmentRecord,
MessageRecord,
UserMetadata,
} from "../../shared/index.js";
} from "../../shared/moderation-types.js";
// Re-export all shared types for backward compatibility
export type {
@@ -26,7 +25,7 @@ export type {
ReviewStatus,
RoleMetadata,
UserMetadata,
} from "../../shared/index.js";
} from "../../shared/moderation-types.js";
// Local-only types (not shared across services)
export type ModerationWsEvent =
@@ -46,3 +46,32 @@ export class ConfigError extends AppError {
this.name = "ConfigError";
}
}
// ---------------------------------------------------------------------------
// Generic error helpers (shared by every module — avoids the repeated
// `err instanceof Error ? err.message : String(err)` pattern, 18+ sites)
// ---------------------------------------------------------------------------
/** Normalize an unknown thrown value to a readable message. */
export function errorMessage(err: unknown): string {
return err instanceof Error ? err.message : String(err);
}
/**
* True when an error code is a transient stream-teardown failure
* (EPIPE / stream destroyed / write-after-end / socket reset).
*
* These are NOT fatal: crashing the gateway on them (e.g. voice stop races,
* ffmpeg stdin closed while we still write) takes the whole bot offline
* mid-operation. Callers that install process-level handlers use this to
* log-and-continue instead of shutting down.
*/
export function isTransientStreamError(err: unknown): boolean {
const code = (err as NodeJS.ErrnoException)?.code ?? "";
return (
code === "EPIPE" ||
code === "ERR_STREAM_DESTROYED" ||
code === "ERR_STREAM_WRITE_AFTER_END" ||
code === "ECONNRESET"
);
}
@@ -1,9 +0,0 @@
export * from "./config/index.js";
export * from "./database/init.js";
export * from "./database/pool.js";
export * from "./database/schema.js";
export * from "./errors/index.js";
export * from "./logger/index.js";
export * from "./moderation-types.js";
export * from "./redis-channels.js";
export * from "./utils/index.js";