vapor / postgres-kit

🐘 Non-blocking, event-driven Swift client for PostgreSQL.
MIT License
188 stars 70 forks source link

Failing to decode enum throws incorrect error #227

Open rausnitz opened 2 years ago

rausnitz commented 2 years ago

Describe the bug

When decoding a Postgres value into a RawRepresentable enum type, if the raw value does not match a valid case of the enum, the following error description is generated:

"Unexpected data type: TEXT. Expected jsonb/json."

That is not an accurate description of the error.

To Reproduce

Reproduced here and copied below: https://github.com/centaurlabs/postgres-kit/commit/375776028fb023872dba6c334a0a8201010ab548#diff-d6c116bb5c868c4835aa93294335dd0ad2125664273437278a43a23ef2cdb17cR149-R170.

func testUnsuccessfullyDecodeModelWithEnum() throws {
    let conn = try PostgresConnection.test(on: self.eventLoop).wait()
    defer { try! conn.close().wait() }

    let rows = try conn.query("SELECT 'bar'::text as foo").wait()
    let row = rows[0]

    struct Test: Codable {
        var foo: TestEnum

        enum TestEnum: String, Codable {
            case foo
        }
    }

    do {
        _ = try row.sql().decode(model: Test.self)
    } catch {
        let errorDescription: String = (error as CustomStringConvertible).description
        XCTAssert(errorDescription == "Unexpected data type: TEXT. Expected jsonb/json.")
    }
}

Expected behavior

The error should say something accurate and not default to saying JSON was expected.

It would be great if it said something like Value "bar" is not a valid raw value for TestEnum. This is tricky because it does not seem straightforward to determine if type on this line is RawRepresentable or anything else that would indicate this is an enum. Maybe someone else will know a good way to do this.

If not, another solution would be to replace "jsonb/json" with String(describing: type) on this line.

Or we could throw a new error altogether.

Environment

Any environment that can run the tests should be able to run the one I added as a demo.