ff-effect 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +4 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/wrap-client.test.ts +86 -59
- package/src/wrap-client.ts +18 -8
package/dist/index.cjs
CHANGED
|
@@ -59,7 +59,10 @@ function wrapClient(opts) {
|
|
|
59
59
|
return (func, overrides) => import_effect3.Effect.tryPromise({
|
|
60
60
|
try: () => func(opts.client),
|
|
61
61
|
catch: (cause) => {
|
|
62
|
-
|
|
62
|
+
if (overrides?.errorHandler) {
|
|
63
|
+
return overrides.errorHandler(cause);
|
|
64
|
+
}
|
|
65
|
+
const message = overrides?.errorMessage != null ? isMessage(overrides.errorMessage) ? overrides.errorMessage : overrides.errorMessage(cause) : void 0;
|
|
63
66
|
return opts.error({
|
|
64
67
|
cause,
|
|
65
68
|
...message != null && { message }
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/extract.ts","../src/run-promise-unwrapped.ts","../src/wrap-client.ts"],"sourcesContent":["export { extract } from './extract.js';\nexport { runPromiseUnwrapped } from './run-promise-unwrapped.js';\nexport { wrapClient } from './wrap-client.js';\n","import { Context, Effect, pipe } from \"effect\";\n\ntype InferClass<T> = T extends new (...args: any[]) => infer R ? R : never;\n\n// biome-ignore lint/suspicious/noExplicitAny: intended\nexport function extract<\n\tP extends any[],\n\tA,\n\tE,\n\tR,\n\tINFERRED_EXCLUDED extends Context.Tag<any, any> = never,\n\tEXCLUDED = InferClass<INFERRED_EXCLUDED>,\n>(\n\teffect: (...params: P) => Effect.Effect<A, E, R>,\n\toptions?: { exclude?: Array<INFERRED_EXCLUDED> }\n): Effect.Effect<\n\t(...params: P) => Effect.Effect<A, E, Extract<R, EXCLUDED>>,\n\tnever,\n\tExclude<R, EXCLUDED>\n> {\n\t// @ts-expect-error quite hard to type, check unit test\n\treturn Effect.gen(function* () {\n\t\tconst runtime = yield* Effect.runtime();\n\n\t\tconst context = runtime.context.pipe(\n\t\t\toptions?.exclude ? Context.omit(...options.exclude) : (e) => e\n\t\t) as Context.Context<Exclude<R, EXCLUDED>>;\n\n\t\treturn (...params: P) =>\n\t\t\tpipe(effect(...params), Effect.provide(context));\n\t});\n}\n","import { Cause, Effect, Exit } from \"effect\";\n\n/**\n * A simple wrapper around Effect.runPromiseExit that throws the error if it's a failure\n **/\nexport async function runPromiseUnwrapped<A, E>(\n\teffect: Effect.Effect<A, E, never>\n) {\n\tconst exit = await Effect.runPromiseExit(effect);\n\treturn Exit.match(exit, {\n\t\tonSuccess: (value) => value,\n\t\tonFailure: (cause) => {\n\t\t\tthrow Cause.isFailType(cause) ? cause.error : cause;\n\t\t},\n\t});\n}\n","import { Effect } from 'effect';\n\ntype Cause = unknown;\ntype Message = string;\nfunction isMessage(x: unknown): x is Message {\n\treturn typeof x === 'string';\n}\n\nexport function wrapClient<CLIENT, ERROR extends Error>(opts: {\n\tclient: CLIENT;\n\terror: (ctx: { cause: Cause; message?: Message }) => ERROR;\n}) {\n\treturn <OUTPUT>(\n\t\tfunc: (client: CLIENT) => Promise<OUTPUT>,\n\t\toverrides?: {
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/extract.ts","../src/run-promise-unwrapped.ts","../src/wrap-client.ts"],"sourcesContent":["export { extract } from './extract.js';\nexport { runPromiseUnwrapped } from './run-promise-unwrapped.js';\nexport { wrapClient } from './wrap-client.js';\n","import { Context, Effect, pipe } from \"effect\";\n\ntype InferClass<T> = T extends new (...args: any[]) => infer R ? R : never;\n\n// biome-ignore lint/suspicious/noExplicitAny: intended\nexport function extract<\n\tP extends any[],\n\tA,\n\tE,\n\tR,\n\tINFERRED_EXCLUDED extends Context.Tag<any, any> = never,\n\tEXCLUDED = InferClass<INFERRED_EXCLUDED>,\n>(\n\teffect: (...params: P) => Effect.Effect<A, E, R>,\n\toptions?: { exclude?: Array<INFERRED_EXCLUDED> }\n): Effect.Effect<\n\t(...params: P) => Effect.Effect<A, E, Extract<R, EXCLUDED>>,\n\tnever,\n\tExclude<R, EXCLUDED>\n> {\n\t// @ts-expect-error quite hard to type, check unit test\n\treturn Effect.gen(function* () {\n\t\tconst runtime = yield* Effect.runtime();\n\n\t\tconst context = runtime.context.pipe(\n\t\t\toptions?.exclude ? Context.omit(...options.exclude) : (e) => e\n\t\t) as Context.Context<Exclude<R, EXCLUDED>>;\n\n\t\treturn (...params: P) =>\n\t\t\tpipe(effect(...params), Effect.provide(context));\n\t});\n}\n","import { Cause, Effect, Exit } from \"effect\";\n\n/**\n * A simple wrapper around Effect.runPromiseExit that throws the error if it's a failure\n **/\nexport async function runPromiseUnwrapped<A, E>(\n\teffect: Effect.Effect<A, E, never>\n) {\n\tconst exit = await Effect.runPromiseExit(effect);\n\treturn Exit.match(exit, {\n\t\tonSuccess: (value) => value,\n\t\tonFailure: (cause) => {\n\t\t\tthrow Cause.isFailType(cause) ? cause.error : cause;\n\t\t},\n\t});\n}\n","import { Effect } from 'effect';\n\ntype Cause = unknown;\ntype Message = string;\nfunction isMessage(x: unknown): x is Message {\n\treturn typeof x === 'string';\n}\n\nexport function wrapClient<CLIENT, ERROR extends Error>(opts: {\n\tclient: CLIENT;\n\terror: (ctx: { cause: Cause; message?: Message }) => ERROR;\n}) {\n\treturn <OUTPUT, OVERRIDEN_ERROR>(\n\t\tfunc: (client: CLIENT) => Promise<OUTPUT>,\n\t\toverrides?: {\n\t\t\terrorHandler?: (cause: Cause) => OVERRIDEN_ERROR;\n\t\t\terrorMessage?: ((cause: Cause) => Message) | Message;\n\t\t},\n\t) =>\n\t\tEffect.tryPromise({\n\t\t\ttry: () => func(opts.client),\n\t\t\tcatch: (cause) => {\n\t\t\t\tif (overrides?.errorHandler) {\n\t\t\t\t\treturn overrides.errorHandler(cause);\n\t\t\t\t}\n\n\t\t\t\tconst message =\n\t\t\t\t\toverrides?.errorMessage != null\n\t\t\t\t\t\t? isMessage(overrides.errorMessage)\n\t\t\t\t\t\t\t? overrides.errorMessage\n\t\t\t\t\t\t\t: overrides.errorMessage(cause)\n\t\t\t\t\t\t: undefined;\n\t\t\t\treturn opts.error({\n\t\t\t\t\tcause,\n\t\t\t\t\t...(message != null && { message }),\n\t\t\t\t});\n\t\t\t},\n\t\t}) as Effect.Effect<\n\t\t\tOUTPUT,\n\t\t\tunknown extends OVERRIDEN_ERROR ? ERROR : OVERRIDEN_ERROR\n\t\t>;\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAAsC;AAK/B,SAAS,QAQf,QACA,SAKC;AAED,SAAO,qBAAO,IAAI,aAAa;AAC9B,UAAM,UAAU,OAAO,qBAAO,QAAQ;AAEtC,UAAM,UAAU,QAAQ,QAAQ;AAAA,MAC/B,SAAS,UAAU,sBAAQ,KAAK,GAAG,QAAQ,OAAO,IAAI,CAAC,MAAM;AAAA,IAC9D;AAEA,WAAO,IAAI,eACV,oBAAK,OAAO,GAAG,MAAM,GAAG,qBAAO,QAAQ,OAAO,CAAC;AAAA,EACjD,CAAC;AACF;;;AC/BA,IAAAA,iBAAoC;AAKpC,eAAsB,oBACrB,QACC;AACD,QAAM,OAAO,MAAM,sBAAO,eAAe,MAAM;AAC/C,SAAO,oBAAK,MAAM,MAAM;AAAA,IACvB,WAAW,CAAC,UAAU;AAAA,IACtB,WAAW,CAAC,UAAU;AACrB,YAAM,qBAAM,WAAW,KAAK,IAAI,MAAM,QAAQ;AAAA,IAC/C;AAAA,EACD,CAAC;AACF;;;ACfA,IAAAC,iBAAuB;AAIvB,SAAS,UAAU,GAA0B;AAC5C,SAAO,OAAO,MAAM;AACrB;AAEO,SAAS,WAAwC,MAGrD;AACF,SAAO,CACN,MACA,cAKA,sBAAO,WAAW;AAAA,IACjB,KAAK,MAAM,KAAK,KAAK,MAAM;AAAA,IAC3B,OAAO,CAAC,UAAU;AACjB,UAAI,WAAW,cAAc;AAC5B,eAAO,UAAU,aAAa,KAAK;AAAA,MACpC;AAEA,YAAM,UACL,WAAW,gBAAgB,OACxB,UAAU,UAAU,YAAY,IAC/B,UAAU,eACV,UAAU,aAAa,KAAK,IAC7B;AACJ,aAAO,KAAK,MAAM;AAAA,QACjB;AAAA,QACA,GAAI,WAAW,QAAQ,EAAE,QAAQ;AAAA,MAClC,CAAC;AAAA,IACF;AAAA,EACD,CAAC;AAIH;","names":["import_effect","import_effect"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -18,8 +18,9 @@ declare function wrapClient<CLIENT, ERROR extends Error>(opts: {
|
|
|
18
18
|
cause: Cause;
|
|
19
19
|
message?: Message;
|
|
20
20
|
}) => ERROR;
|
|
21
|
-
}): <OUTPUT>(func: (client: CLIENT) => Promise<OUTPUT>, overrides?: {
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
}): <OUTPUT, OVERRIDEN_ERROR>(func: (client: CLIENT) => Promise<OUTPUT>, overrides?: {
|
|
22
|
+
errorHandler?: (cause: Cause) => OVERRIDEN_ERROR;
|
|
23
|
+
errorMessage?: ((cause: Cause) => Message) | Message;
|
|
24
|
+
}) => Effect.Effect<OUTPUT, unknown extends OVERRIDEN_ERROR ? ERROR : OVERRIDEN_ERROR>;
|
|
24
25
|
|
|
25
26
|
export { extract, runPromiseUnwrapped, wrapClient };
|
package/dist/index.d.ts
CHANGED
|
@@ -18,8 +18,9 @@ declare function wrapClient<CLIENT, ERROR extends Error>(opts: {
|
|
|
18
18
|
cause: Cause;
|
|
19
19
|
message?: Message;
|
|
20
20
|
}) => ERROR;
|
|
21
|
-
}): <OUTPUT>(func: (client: CLIENT) => Promise<OUTPUT>, overrides?: {
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
}): <OUTPUT, OVERRIDEN_ERROR>(func: (client: CLIENT) => Promise<OUTPUT>, overrides?: {
|
|
22
|
+
errorHandler?: (cause: Cause) => OVERRIDEN_ERROR;
|
|
23
|
+
errorMessage?: ((cause: Cause) => Message) | Message;
|
|
24
|
+
}) => Effect.Effect<OUTPUT, unknown extends OVERRIDEN_ERROR ? ERROR : OVERRIDEN_ERROR>;
|
|
24
25
|
|
|
25
26
|
export { extract, runPromiseUnwrapped, wrapClient };
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,10 @@ function wrapClient(opts) {
|
|
|
31
31
|
return (func, overrides) => Effect3.tryPromise({
|
|
32
32
|
try: () => func(opts.client),
|
|
33
33
|
catch: (cause) => {
|
|
34
|
-
|
|
34
|
+
if (overrides?.errorHandler) {
|
|
35
|
+
return overrides.errorHandler(cause);
|
|
36
|
+
}
|
|
37
|
+
const message = overrides?.errorMessage != null ? isMessage(overrides.errorMessage) ? overrides.errorMessage : overrides.errorMessage(cause) : void 0;
|
|
35
38
|
return opts.error({
|
|
36
39
|
cause,
|
|
37
40
|
...message != null && { message }
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/extract.ts","../src/run-promise-unwrapped.ts","../src/wrap-client.ts"],"sourcesContent":["import { Context, Effect, pipe } from \"effect\";\n\ntype InferClass<T> = T extends new (...args: any[]) => infer R ? R : never;\n\n// biome-ignore lint/suspicious/noExplicitAny: intended\nexport function extract<\n\tP extends any[],\n\tA,\n\tE,\n\tR,\n\tINFERRED_EXCLUDED extends Context.Tag<any, any> = never,\n\tEXCLUDED = InferClass<INFERRED_EXCLUDED>,\n>(\n\teffect: (...params: P) => Effect.Effect<A, E, R>,\n\toptions?: { exclude?: Array<INFERRED_EXCLUDED> }\n): Effect.Effect<\n\t(...params: P) => Effect.Effect<A, E, Extract<R, EXCLUDED>>,\n\tnever,\n\tExclude<R, EXCLUDED>\n> {\n\t// @ts-expect-error quite hard to type, check unit test\n\treturn Effect.gen(function* () {\n\t\tconst runtime = yield* Effect.runtime();\n\n\t\tconst context = runtime.context.pipe(\n\t\t\toptions?.exclude ? Context.omit(...options.exclude) : (e) => e\n\t\t) as Context.Context<Exclude<R, EXCLUDED>>;\n\n\t\treturn (...params: P) =>\n\t\t\tpipe(effect(...params), Effect.provide(context));\n\t});\n}\n","import { Cause, Effect, Exit } from \"effect\";\n\n/**\n * A simple wrapper around Effect.runPromiseExit that throws the error if it's a failure\n **/\nexport async function runPromiseUnwrapped<A, E>(\n\teffect: Effect.Effect<A, E, never>\n) {\n\tconst exit = await Effect.runPromiseExit(effect);\n\treturn Exit.match(exit, {\n\t\tonSuccess: (value) => value,\n\t\tonFailure: (cause) => {\n\t\t\tthrow Cause.isFailType(cause) ? cause.error : cause;\n\t\t},\n\t});\n}\n","import { Effect } from 'effect';\n\ntype Cause = unknown;\ntype Message = string;\nfunction isMessage(x: unknown): x is Message {\n\treturn typeof x === 'string';\n}\n\nexport function wrapClient<CLIENT, ERROR extends Error>(opts: {\n\tclient: CLIENT;\n\terror: (ctx: { cause: Cause; message?: Message }) => ERROR;\n}) {\n\treturn <OUTPUT>(\n\t\tfunc: (client: CLIENT) => Promise<OUTPUT>,\n\t\toverrides?: {
|
|
1
|
+
{"version":3,"sources":["../src/extract.ts","../src/run-promise-unwrapped.ts","../src/wrap-client.ts"],"sourcesContent":["import { Context, Effect, pipe } from \"effect\";\n\ntype InferClass<T> = T extends new (...args: any[]) => infer R ? R : never;\n\n// biome-ignore lint/suspicious/noExplicitAny: intended\nexport function extract<\n\tP extends any[],\n\tA,\n\tE,\n\tR,\n\tINFERRED_EXCLUDED extends Context.Tag<any, any> = never,\n\tEXCLUDED = InferClass<INFERRED_EXCLUDED>,\n>(\n\teffect: (...params: P) => Effect.Effect<A, E, R>,\n\toptions?: { exclude?: Array<INFERRED_EXCLUDED> }\n): Effect.Effect<\n\t(...params: P) => Effect.Effect<A, E, Extract<R, EXCLUDED>>,\n\tnever,\n\tExclude<R, EXCLUDED>\n> {\n\t// @ts-expect-error quite hard to type, check unit test\n\treturn Effect.gen(function* () {\n\t\tconst runtime = yield* Effect.runtime();\n\n\t\tconst context = runtime.context.pipe(\n\t\t\toptions?.exclude ? Context.omit(...options.exclude) : (e) => e\n\t\t) as Context.Context<Exclude<R, EXCLUDED>>;\n\n\t\treturn (...params: P) =>\n\t\t\tpipe(effect(...params), Effect.provide(context));\n\t});\n}\n","import { Cause, Effect, Exit } from \"effect\";\n\n/**\n * A simple wrapper around Effect.runPromiseExit that throws the error if it's a failure\n **/\nexport async function runPromiseUnwrapped<A, E>(\n\teffect: Effect.Effect<A, E, never>\n) {\n\tconst exit = await Effect.runPromiseExit(effect);\n\treturn Exit.match(exit, {\n\t\tonSuccess: (value) => value,\n\t\tonFailure: (cause) => {\n\t\t\tthrow Cause.isFailType(cause) ? cause.error : cause;\n\t\t},\n\t});\n}\n","import { Effect } from 'effect';\n\ntype Cause = unknown;\ntype Message = string;\nfunction isMessage(x: unknown): x is Message {\n\treturn typeof x === 'string';\n}\n\nexport function wrapClient<CLIENT, ERROR extends Error>(opts: {\n\tclient: CLIENT;\n\terror: (ctx: { cause: Cause; message?: Message }) => ERROR;\n}) {\n\treturn <OUTPUT, OVERRIDEN_ERROR>(\n\t\tfunc: (client: CLIENT) => Promise<OUTPUT>,\n\t\toverrides?: {\n\t\t\terrorHandler?: (cause: Cause) => OVERRIDEN_ERROR;\n\t\t\terrorMessage?: ((cause: Cause) => Message) | Message;\n\t\t},\n\t) =>\n\t\tEffect.tryPromise({\n\t\t\ttry: () => func(opts.client),\n\t\t\tcatch: (cause) => {\n\t\t\t\tif (overrides?.errorHandler) {\n\t\t\t\t\treturn overrides.errorHandler(cause);\n\t\t\t\t}\n\n\t\t\t\tconst message =\n\t\t\t\t\toverrides?.errorMessage != null\n\t\t\t\t\t\t? isMessage(overrides.errorMessage)\n\t\t\t\t\t\t\t? overrides.errorMessage\n\t\t\t\t\t\t\t: overrides.errorMessage(cause)\n\t\t\t\t\t\t: undefined;\n\t\t\t\treturn opts.error({\n\t\t\t\t\tcause,\n\t\t\t\t\t...(message != null && { message }),\n\t\t\t\t});\n\t\t\t},\n\t\t}) as Effect.Effect<\n\t\t\tOUTPUT,\n\t\t\tunknown extends OVERRIDEN_ERROR ? ERROR : OVERRIDEN_ERROR\n\t\t>;\n}"],"mappings":";AAAA,SAAS,SAAS,QAAQ,YAAY;AAK/B,SAAS,QAQf,QACA,SAKC;AAED,SAAO,OAAO,IAAI,aAAa;AAC9B,UAAM,UAAU,OAAO,OAAO,QAAQ;AAEtC,UAAM,UAAU,QAAQ,QAAQ;AAAA,MAC/B,SAAS,UAAU,QAAQ,KAAK,GAAG,QAAQ,OAAO,IAAI,CAAC,MAAM;AAAA,IAC9D;AAEA,WAAO,IAAI,WACV,KAAK,OAAO,GAAG,MAAM,GAAG,OAAO,QAAQ,OAAO,CAAC;AAAA,EACjD,CAAC;AACF;;;AC/BA,SAAS,OAAO,UAAAA,SAAQ,YAAY;AAKpC,eAAsB,oBACrB,QACC;AACD,QAAM,OAAO,MAAMA,QAAO,eAAe,MAAM;AAC/C,SAAO,KAAK,MAAM,MAAM;AAAA,IACvB,WAAW,CAAC,UAAU;AAAA,IACtB,WAAW,CAAC,UAAU;AACrB,YAAM,MAAM,WAAW,KAAK,IAAI,MAAM,QAAQ;AAAA,IAC/C;AAAA,EACD,CAAC;AACF;;;ACfA,SAAS,UAAAC,eAAc;AAIvB,SAAS,UAAU,GAA0B;AAC5C,SAAO,OAAO,MAAM;AACrB;AAEO,SAAS,WAAwC,MAGrD;AACF,SAAO,CACN,MACA,cAKAA,QAAO,WAAW;AAAA,IACjB,KAAK,MAAM,KAAK,KAAK,MAAM;AAAA,IAC3B,OAAO,CAAC,UAAU;AACjB,UAAI,WAAW,cAAc;AAC5B,eAAO,UAAU,aAAa,KAAK;AAAA,MACpC;AAEA,YAAM,UACL,WAAW,gBAAgB,OACxB,UAAU,UAAU,YAAY,IAC/B,UAAU,eACV,UAAU,aAAa,KAAK,IAC7B;AACJ,aAAO,KAAK,MAAM;AAAA,QACjB;AAAA,QACA,GAAI,WAAW,QAAQ,EAAE,QAAQ;AAAA,MAClC,CAAC;AAAA,IACF;AAAA,EACD,CAAC;AAIH;","names":["Effect","Effect"]}
|
package/package.json
CHANGED
package/src/wrap-client.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Effect } from 'effect';
|
|
2
|
-
import { expect, test } from 'vitest';
|
|
1
|
+
import { Data, Effect } from 'effect';
|
|
2
|
+
import { describe, expect, test } from 'vitest';
|
|
3
3
|
import { wrapClient } from './wrap-client.js';
|
|
4
4
|
|
|
5
5
|
class TestError extends Error {
|
|
@@ -28,60 +28,87 @@ test('resolves successfully', () =>
|
|
|
28
28
|
expect(result).toBe('test-value');
|
|
29
29
|
}).pipe(Effect.runPromise));
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
31
|
+
describe('rejects', () => {
|
|
32
|
+
test('default - rejects without message when no overrides provided', () =>
|
|
33
|
+
Effect.gen(function* () {
|
|
34
|
+
const client: TestClient = { value: 'test-value' };
|
|
35
|
+
const wrap = wrapClient({
|
|
36
|
+
client,
|
|
37
|
+
error: ({ cause, message }) => new TestError(cause, message),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const causedBy = new Error('original error');
|
|
41
|
+
const effect = wrap(() => Promise.reject(causedBy));
|
|
42
|
+
|
|
43
|
+
const result = yield* Effect.flip(effect);
|
|
44
|
+
|
|
45
|
+
expect(result).toBeInstanceOf(TestError);
|
|
46
|
+
expect(result._cause).toBe(causedBy);
|
|
47
|
+
expect(result._message).toBeUndefined();
|
|
48
|
+
}).pipe(Effect.runPromise));
|
|
49
|
+
|
|
50
|
+
test('errorHandler override', () =>
|
|
51
|
+
Effect.gen(function* () {
|
|
52
|
+
class CustomError extends Data.TaggedError('CustomError')<{
|
|
53
|
+
cause: unknown;
|
|
54
|
+
}> {}
|
|
55
|
+
|
|
56
|
+
const client: TestClient = { value: 'test-value' };
|
|
57
|
+
const wrap = wrapClient({
|
|
58
|
+
client,
|
|
59
|
+
error: ({ cause, message }) => new TestError(cause, message),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const causedBy = new Error('original error');
|
|
63
|
+
const effect = wrap(() => Promise.reject(causedBy), {
|
|
64
|
+
errorHandler: (cause) => new CustomError({ cause }),
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const result = yield* Effect.flip(effect);
|
|
68
|
+
|
|
69
|
+
expect(result).toBeInstanceOf(CustomError);
|
|
70
|
+
expect(result.cause).toBe(causedBy);
|
|
71
|
+
}).pipe(Effect.runPromise));
|
|
72
|
+
|
|
73
|
+
describe('errorMessage override', () => {
|
|
74
|
+
test('string', () =>
|
|
75
|
+
Effect.gen(function* () {
|
|
76
|
+
const client: TestClient = { value: 'test-value' };
|
|
77
|
+
const wrap = wrapClient({
|
|
78
|
+
client,
|
|
79
|
+
error: ({ cause, message }) => new TestError(cause, message),
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const causedBy = new Error('original error');
|
|
83
|
+
const effect = wrap(() => Promise.reject(causedBy), {
|
|
84
|
+
errorMessage: 'custom message',
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const result = yield* Effect.flip(effect);
|
|
88
|
+
|
|
89
|
+
expect(result).toBeInstanceOf(TestError);
|
|
90
|
+
expect(result._cause).toBe(causedBy);
|
|
91
|
+
expect(result._message).toBe('custom message');
|
|
92
|
+
}).pipe(Effect.runPromise));
|
|
93
|
+
|
|
94
|
+
test('handler', () =>
|
|
95
|
+
Effect.gen(function* () {
|
|
96
|
+
const client: TestClient = { value: 'test-value' };
|
|
97
|
+
const wrap = wrapClient({
|
|
98
|
+
client,
|
|
99
|
+
error: ({ cause, message }) => new TestError(cause, message),
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const causedBy = new Error('original error');
|
|
103
|
+
const effect = wrap(() => Promise.reject(causedBy), {
|
|
104
|
+
errorMessage: (cause) => `Error: ${(cause as Error).message}`,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const result = yield* Effect.flip(effect);
|
|
108
|
+
|
|
109
|
+
expect(result).toBeInstanceOf(TestError);
|
|
110
|
+
expect(result._cause).toBe(causedBy);
|
|
111
|
+
expect(result._message).toBe('Error: original error');
|
|
112
|
+
}).pipe(Effect.runPromise));
|
|
113
|
+
});
|
|
114
|
+
});
|
package/src/wrap-client.ts
CHANGED
|
@@ -10,23 +10,33 @@ export function wrapClient<CLIENT, ERROR extends Error>(opts: {
|
|
|
10
10
|
client: CLIENT;
|
|
11
11
|
error: (ctx: { cause: Cause; message?: Message }) => ERROR;
|
|
12
12
|
}) {
|
|
13
|
-
return <OUTPUT>(
|
|
13
|
+
return <OUTPUT, OVERRIDEN_ERROR>(
|
|
14
14
|
func: (client: CLIENT) => Promise<OUTPUT>,
|
|
15
|
-
overrides?: {
|
|
15
|
+
overrides?: {
|
|
16
|
+
errorHandler?: (cause: Cause) => OVERRIDEN_ERROR;
|
|
17
|
+
errorMessage?: ((cause: Cause) => Message) | Message;
|
|
18
|
+
},
|
|
16
19
|
) =>
|
|
17
20
|
Effect.tryPromise({
|
|
18
21
|
try: () => func(opts.client),
|
|
19
22
|
catch: (cause) => {
|
|
23
|
+
if (overrides?.errorHandler) {
|
|
24
|
+
return overrides.errorHandler(cause);
|
|
25
|
+
}
|
|
26
|
+
|
|
20
27
|
const message =
|
|
21
|
-
overrides?.
|
|
22
|
-
? isMessage(overrides.
|
|
23
|
-
? overrides.
|
|
24
|
-
: overrides.
|
|
28
|
+
overrides?.errorMessage != null
|
|
29
|
+
? isMessage(overrides.errorMessage)
|
|
30
|
+
? overrides.errorMessage
|
|
31
|
+
: overrides.errorMessage(cause)
|
|
25
32
|
: undefined;
|
|
26
33
|
return opts.error({
|
|
27
34
|
cause,
|
|
28
35
|
...(message != null && { message }),
|
|
29
36
|
});
|
|
30
37
|
},
|
|
31
|
-
})
|
|
32
|
-
|
|
38
|
+
}) as Effect.Effect<
|
|
39
|
+
OUTPUT,
|
|
40
|
+
unknown extends OVERRIDEN_ERROR ? ERROR : OVERRIDEN_ERROR
|
|
41
|
+
>;
|
|
42
|
+
}
|