Merge commit '3c60637c1a27da8ba66888de518d58d5707801f2' as 'repos/effect-smol'
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
import { assert, describe, it } from "@effect/vitest"
|
||||
import { assertNone } from "@effect/vitest/utils"
|
||||
import { Cause, Effect } from "effect"
|
||||
import {
|
||||
causeResponseStripped,
|
||||
HttpServerError,
|
||||
InternalError,
|
||||
isHttpServerError,
|
||||
RequestParseError,
|
||||
ResponseError,
|
||||
RouteNotFound,
|
||||
ServeError
|
||||
} from "effect/unstable/http/HttpServerError"
|
||||
import * as HttpServerRequest from "effect/unstable/http/HttpServerRequest"
|
||||
import * as Respondable from "effect/unstable/http/HttpServerRespondable"
|
||||
import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse"
|
||||
|
||||
const makeRequest = (method: string, url: string) => HttpServerRequest.fromWeb(new Request(url, { method }))
|
||||
const makeResponse = (status: number) => HttpServerResponse.empty({ status })
|
||||
|
||||
describe("HttpServerError", () => {
|
||||
describe("reason messages", () => {
|
||||
it("formats request reason messages", () => {
|
||||
const request = makeRequest("POST", "http://example.com/widgets")
|
||||
const parseError = new RequestParseError({
|
||||
request,
|
||||
description: "invalid body"
|
||||
})
|
||||
const routeNotFound = new RouteNotFound({ request })
|
||||
|
||||
assert.strictEqual(parseError.message, "RequestParseError (POST /widgets): invalid body")
|
||||
assert.strictEqual(routeNotFound.message, "RouteNotFound (POST /widgets)")
|
||||
})
|
||||
|
||||
it("formats response reason messages", () => {
|
||||
const request = makeRequest("GET", "http://example.com/tea")
|
||||
const response = makeResponse(418)
|
||||
const responseError = new ResponseError({
|
||||
request,
|
||||
response,
|
||||
description: "short and stout"
|
||||
})
|
||||
|
||||
assert.strictEqual(responseError.message, "ResponseError (418 GET /tea): short and stout")
|
||||
})
|
||||
})
|
||||
|
||||
describe("wrapper behavior", () => {
|
||||
it("delegates message and accessors", () => {
|
||||
const request = makeRequest("GET", "http://example.com/ok")
|
||||
const response = makeResponse(503)
|
||||
const reason = new ResponseError({ request, response })
|
||||
const error = new HttpServerError({ reason })
|
||||
|
||||
assert.strictEqual(error.message, reason.message)
|
||||
assert.strictEqual(error.request, request)
|
||||
assert.strictEqual(error.response, response)
|
||||
assert.strictEqual(error.reason, reason)
|
||||
})
|
||||
|
||||
it("forwards the reason cause", () => {
|
||||
const request = makeRequest("GET", "http://example.com/boom")
|
||||
const cause = new Error("boom")
|
||||
const reason = new InternalError({ request, cause })
|
||||
const error = new HttpServerError({ reason })
|
||||
|
||||
assert.strictEqual(reason.cause, cause)
|
||||
assert.strictEqual(error.cause, cause)
|
||||
})
|
||||
})
|
||||
|
||||
describe("respondable mapping", () => {
|
||||
it.effect("maps reasons to status codes", () =>
|
||||
Effect.gen(function*() {
|
||||
const request = makeRequest("GET", "http://example.com/status")
|
||||
const response = makeResponse(418)
|
||||
const cases: ReadonlyArray<readonly [Respondable.Respondable, number]> = [
|
||||
[new RequestParseError({ request }), 400],
|
||||
[new RouteNotFound({ request }), 404],
|
||||
[new InternalError({ request }), 500],
|
||||
[new ResponseError({ request, response }), 500],
|
||||
[new HttpServerError({ reason: new RequestParseError({ request }) }), 400]
|
||||
]
|
||||
|
||||
for (const [respondable, status] of cases) {
|
||||
const resolved = yield* Respondable.toResponse(respondable)
|
||||
assert.strictEqual(resolved.status, status)
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
describe("isHttpServerError", () => {
|
||||
it("matches wrapper only", () => {
|
||||
const request = makeRequest("GET", "http://example.com/check")
|
||||
const wrapper = new HttpServerError({
|
||||
reason: new RouteNotFound({ request })
|
||||
})
|
||||
|
||||
assert.isTrue(isHttpServerError(wrapper))
|
||||
assert.isFalse(isHttpServerError(new RouteNotFound({ request })))
|
||||
assert.isFalse(isHttpServerError(new ServeError({ cause: new Error("boom") })))
|
||||
assert.isFalse(isHttpServerError({ _tag: "HttpServerError" }))
|
||||
})
|
||||
})
|
||||
|
||||
describe("causeResponseStripped", () => {
|
||||
it("returns none cause for response defects", () => {
|
||||
const response = makeResponse(418)
|
||||
const [out, cause] = causeResponseStripped(Cause.die(response))
|
||||
assert.strictEqual(out, response)
|
||||
assertNone(cause)
|
||||
})
|
||||
|
||||
it("returns some cause for non-response failures", () => {
|
||||
const request = makeRequest("GET", "http://example.com/fail")
|
||||
const [out, cause] = causeResponseStripped(Cause.fail(new RouteNotFound({ request })))
|
||||
assert.strictEqual(out.status, 500)
|
||||
assert.strictEqual(cause._tag, "Some")
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user