-
-
Save kandros/a727135eff5840d68383b10aa33cfb52 to your computer and use it in GitHub Desktop.
import * as PgDrizzle from "@effect/sql-drizzle/Pg"; | |
import { PgClient } from "@effect/sql-pg"; | |
import { Config, Effect } from "effect"; | |
import * as schema from "~/lib/server/schema"; | |
const PgLive = PgClient.layerConfig({ | |
url: Config.redacted("DATABASE_URL"), | |
}); | |
export class DrizzleClient extends Effect.Service<DrizzleClient>()("app/DrizzleClient", { | |
dependencies: [PgLive], | |
effect: Effect.gen(function* () { | |
const db = yield* PgDrizzle.make<typeof schema>({ | |
schema: schema, | |
}); | |
return db; | |
}), | |
}) {} | |
hi @kandros, thanks for this. I am having trouble implementing error handling with a runtime. Can you give an example for that too?
Can you give an example? I’m using it with a managed runtime
same here
// ManagedRuntime.ManagedRuntime<Database | Auth, ConfigError | SqlError>
export const AppRuntime = ManagedRuntime.make(AppLive);
Auth
here is an another service which depends on Database.Default
and the runtime is giving ConfigError
or SqlError
but how do you handle it?
when i call db query i don't get those errors in Effect.catchTags
const program = Effect.gen(function* () {
const db = yield* Database;
const todos = yield* Effect.tryPromise(() =>
db.select().from(todoTable)
);
return todos
}).pipe(
Effect.catchTag("", () => {})
)
await AppRuntime.runPromise(program)
Use yield* of the db
const db = yield* DrizzleClient;
const result = yield* db.insert(documents).values(input).returning();
By using tryPromise you exit “effect land” and lose the errors
Thanks man! can you give me an example of how you are mapping SqlError.
i am getting this error cause and not able to get the PostgresError :(
(FiberFailure) SqlError: Failed to execute statement
at cause (/home/akshat/Documents/git/commander/node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected][email protected]_42ab70da82d8a05f56a95887e3aec16b/node_modules/@effect/sql-pg/src/PgClient.ts:220:31)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5) {
[cause]: PostgresError: duplicate key value violates unique constraint "course_code_unique"
at ErrorResponse (file:///home/akshat/Documents/git/commander/node_modules/.pnpm/[email protected]/node_modules/postgres/src/connection.js:794:26)
at handle (file:///home/akshat/Documents/git/commander/node_modules/.pnpm/[email protected]/node_modules/postgres/src/connection.js:480:6)
at Socket.data (file:///home/akshat/Documents/git/commander/node_modules/.pnpm/[email protected]/node_modules/postgres/src/connection.js:315:9)
at Socket.emit (node:events:518:28)
at addChunk (node:internal/streams/readable:561:12)
at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)
at Readable.push (node:internal/streams/readable:392:5)
at TCP.onStreamRead (node:internal/stream_base_commons:189:23)
at TCP.callbackTrampoline (node:internal/async_hooks:130:17)
}```
yeah unfortunately I cannot use PostgresError from the postgres library either. I have to utils to map the SqlError to original error data. I'm not at the computer now, will add this later
thanks!
thanks!
this is the abomination Im using while waiting the native Drizzle effect package 😅
the json stringify and parse is to get to some detail only available during serialization (calling toJSON methods internally) or errors that are not exposed
import { SqlError } from "@effect/sql/SqlError";
export function extractSqlErrorDetails(sqlError: SqlError) {
const jsonStr = JSON.stringify(sqlError);
const parsed = JSON.parse(jsonStr);
function findPostgresErrorInJson(obj: any): any {
if (obj && typeof obj === "object") {
if (obj.name === "PostgresError") {
return obj;
}
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
const result = findPostgresErrorInJson(obj[key]);
if (result) return result;
}
}
}
return null;
}
const pgError = findPostgresErrorInJson(parsed);
if (pgError) {
return {
code: pgError.code,
detail: pgError.detail,
constraint: pgError.constraint_name,
schema: pgError.schema_name,
table: pgError.table_name,
};
}
return null;
}
result is like
{
code: "23505",
detail: "Key (name)=(due) already exists.",
constraint: "test_name_key",
schema: "public",
table: "test",
}
thank you @kandros! I was stuck on this for a long time :)
Please update this as well when there is a better way to handle this 🙏
hi @kandros, thanks for this. I am having trouble implementing error handling with a runtime. Can you give an example for that too?