Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make MultipartParserError Public #112

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

nakul-py
Copy link

@nakul-py nakul-py commented Feb 4, 2025

Summary

This PR makes the MultipartParserError publicly accessible within the MultipartKit package.

Fixes #111

@nakul-py nakul-py requested review from 0xTim and gwynne as code owners February 4, 2025 13:46
Copy link
Member

@ptoffy ptoffy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, however this won't roll as it is. If we make the enum public as it is it will be set in stone and we won't be able to update it without breaking the API. Could you follow this approach instead? https://github.com/vapor/jwt-kit/blob/main/Sources/JWTKit/JWTError.swift

@nakul-py nakul-py requested a review from ptoffy February 4, 2025 14:35
@nakul-py nakul-py requested a review from MahdiBM February 4, 2025 15:52
Copy link
Contributor

@MahdiBM MahdiBM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @nakul-py this is much better. We need some small changes though.

Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
@nakul-py nakul-py requested a review from MahdiBM February 4, 2025 16:37
Copy link
Contributor

@MahdiBM MahdiBM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final changes hopefully, from my side at least.

Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
@nakul-py nakul-py requested a review from MahdiBM February 5, 2025 04:32
Copy link
Contributor

@MahdiBM MahdiBM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me other than these 2 spaces. @ptoffy please take a look.

Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
@nakul-py nakul-py requested a review from MahdiBM February 5, 2025 12:42
Copy link
Member

@ptoffy ptoffy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few nits but looking good

Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
Sources/MultipartKit/MultipartParserError.swift Outdated Show resolved Hide resolved
@ptoffy
Copy link
Member

ptoffy commented Feb 5, 2025

Also @nakul-py this should go through a swift-format pass ideally

@adam-fowler
Copy link
Contributor

With the error constructed like this there is no way to extract the reason associated values.

@nakul-py nakul-py requested a review from ptoffy February 6, 2025 05:15
@adam-fowler
Copy link
Contributor

There is still an issue here in that I cannot easily catch these errors without know the reason string eg

do {
    try multipartFormThings()
} catch let error as MultipartParserError where error == .invalidHeader("I need to know what string this is") {
    ...
}

@ptoffy Are the associated strings in the error necessary? If they are can we do something like this https://github.com/apple/swift-nio/blob/main/Sources/NIOFileSystem/FileSystemError.swift where the code and reason are separate.

@ptoffy
Copy link
Member

ptoffy commented Feb 6, 2025

I think as I said before we should follow JWTKit's example and add something like https://github.com/vapor/jwt-kit/blob/main/Sources/JWTKit/JWTError.swift#L90 so you can do

catch let error as MultipartParserError where error.errorType == .invalidHeader

and you then have access to the error.reason if you need it

@MahdiBM
Copy link
Contributor

MahdiBM commented Feb 6, 2025

To be honest I'd prefer to just have an enum with a new case case __DO_NOT_USE_OR_ELSE__.
Then we can keep the pattern matching and all the enum goodies (other than exhaustive switches).

@adam-fowler
Copy link
Contributor

To be honest I'd prefer to just have an enum with a new case case __DO_NOT_USE_OR_ELSE__. Then we can keep the pattern matching and all the enum goodies (other than exhaustive switches).

How does adding a DO_NOT_USE_OR_ELSE case help?

}
}

private struct Backing: Equatable, Sendable {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why you need the Backing type. What is this giving us over just adding the following to MultipartParserError

let errorType: ErrorType
let reason: String?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use the Backing type because it provides a single place to modify error-related data without exposing too much detail in MultipartParserError.
And If we later want to add more fields (e.g., identifier, underlyingError, or HTTPStatusCode), we can do so without cluttering the main struct.

@adam-fowler will you in the favour of remove Backing type.

@MahdiBM
Copy link
Contributor

MahdiBM commented Feb 7, 2025

How does adding a __DO_NOT_USE_OR_ELSE__ case help?

Well if there is such a case, it solves the exhaustive switch problem. Then we can just mark the enum as public.
I saw it somewhere else before too ... an Apple repo I think ... I think even Fabian approved that? can't remember more.

@0xTim
Copy link
Member

0xTim commented Feb 11, 2025

Well if there is such a case, it solves the exhaustive switch problem. Then we can just mark the enum as public.
I saw it somewhere else before too ... an Apple repo I think ... I think even Fabian approved that? can't remember more.

I'd vote not to use this - it's not a particularly nice solution and means that any new cases get blackholed into that catch all that just causes confusion because now people have to switch over the DO_NOT_USE_OR_ELSE case. We should stick with the approach we've taken in other repos until non-frozen enums land

@MahdiBM
Copy link
Contributor

MahdiBM commented Feb 11, 2025

It does have downsides, but the upside is it's much easier to maintain and you can use associated values with each case in a much nicer way. Also get the pattern matching stuff like in catch blocks.

I would go this route personally, but I don't think y'all like this (I mean you mentioned it too) so I'm just trying to explain the approach.
For this PR we can go whatever sensible route you'd want, like what we have in JWTKit, PostgresNIO etc...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make MultipartParserError public
5 participants