Add functionality to catch many upload problems at once and return them all#141
Add functionality to catch many upload problems at once and return them all#141
Conversation
…to cause some issues with encoding
|
My other PR only contains one change, which yours also contains, so I'll close that one. For clarity, I'll just re-iterate that this deals with the backend side of #68, but doesn't add the client component. Also, there's more that can be done to validate the CSV upload, but this is a start. That can probably be done separate from this. |
|
The next step for me is to implement some json testing but that's tricky without examples. Are there existing examples, @waxlamp, or will I have to generate some? |
|
What do mean by "json testing"? |
|
Sorry, that wasn't clear. I meant json upload validation, i.e. verifying the structure is correct (like we've done with CSV). |
…ide of the main flask route
|
There is currently no validation for the nested json file structure so I've opened a new issue for that (#159). |
|
@AlmightyYakob making those changes has broken the validation tests since they now don't return the errors, they raise the error instead. Any idea how we can handle this? Importing |
|
I think you can have |
|
Ready for review @AlmightyYakob @waxlamp |
|
I think you could also probably catch the exception yourself, then run the asserts in the exception handler. |
|
Is that a preferable solution compared to what I just pushed? |
|
I think the preferred solution is something like: Pytest docs regarding this. FWIW I've testing this method locally and it does work, and still allows us to make those assertions. |
This reverts commit b7941f7.
|
@AlmightyYakob, would the In any case, that pattern gets us the best of both worlds: you can assert that the function raises an exception, and you can examine the structure of that exception too. |
|
Yeah I like it. Can you review my last commit and see if that aligns better with the new tests |
I think you may be able to, but it's not necessary. I prefer to not include that line in the scope, because the only line that would raise the exception is the call to |
Ah so the block just converts a try-except into a linear flow, neat. |
Looks right to me! |
Yes, and also will fail the test if the exception is not raised, which is very handy. |
| try: | ||
| body = input.decode("utf8") | ||
| except UnicodeDecodeError: | ||
| raise DecodeFailed([{"error": "unsupported", "detail": "not utf8"}]) |
There was a problem hiding this comment.
I think the error should read "utf8", and the detail should get whatever error message or error data UnicodeDecodeError provides.
There was a problem hiding this comment.
Sorry, I should have caught this earlier, but DecodeFailed ought to just receive a single argument value, rather than a list, and that value should just be the string value of the UnicodeDecodeError object.
So I would change this line to take in str(e), and change the definition of DecodeFailed to reflect that it's expecting just a string to describe how the decode failed.
There was a problem hiding this comment.
I agree that this is probably best for this one function but since ValidationFailed returns {"errors": errors} maybe we should be consistent? This would allow us to do just one check from the client.
There was a problem hiding this comment.
I don't think there's any reason for DecodeFailed to be made consistent with ValidationFailed -- they are different kinds of error conditions. DecodeFailed is really just our variant of UnicodeDecodeError, which does signal a single error, so we should be consistent with that.
There was a problem hiding this comment.
Oh I see.
I think ValidationError should also lose the "errors" dict format. Let's change both.
There was a problem hiding this comment.
The problem with that solution is that ValidationError can return multiple errors. How should we update that to handle the multiple errors?
There was a problem hiding this comment.
It already handles multiple errors properly; the change here is in how it reports those errors. It can just return the JSONified string representing the list of errors, instead of the JSON object with the errors key that it currently uses.
…ltinet into upload-validation-errors
Right now this just deals with the csv uploader. Looks like some of this work overlaps with @AlmightyYakob but expands functionality to catch many errors in one pass and to catch decoding errors. (closes #101)