question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Combine errors from nested `use_args` calls so that mixed locations still provide full errors in webargs 6.x

See original GitHub issue

Won’t we need to merge error messages for the stacked case?

@use_args({"related_id": fields.Str(required=True))}, location="query"})
@use_args({"name": fields.Str(required=True))}, location="json")
{"related_id": ['Missing...'], "name": ["Missing..."]}

_Originally posted by @sloria in https://github.com/marshmallow-code/webargs/issues/419#issuecomment-525765453_

Supporting this is desirable, since otherwise you only get partial information about validation failures. IMO, the worst part is this: the behavior depends on the order of your use_args calls.

I’ve been thinking about this only a little bit since that issue and I think what’s best is that use_args calls stash their arguments somewhere and then process them “all at once” before the user-supplied function.

One potential implementation path:

  • use_args adds its arguments to some private attribute of the decorated function like func.__webargs_use_args_schemas (initialized as an empty list)
  • the innermost use_args call walks all of the __webargs_use_args_schemas data and evaluates all of it capturing and combining any ValidationErrors
  • outer use_args calls add data to the “schema list” but return the function they were given without trying to do any parsing
    • we could detect this by having the innermost use_args set a flag like __webargs_is_use_args_wrapped which we check with hasattr

I’d also like to explore whether or not it would be safe to replace the use_args callable with a callable object of our own design. That might make the implementation simpler than proposed above, but I’m not sure if it will work with all frameworks.

Some questions:

  1. Is this actually a good idea? Just because we can do this and it would be nice for users doesn’t mean that it’s worth the complexity. I’m worried that I’m looking at what’s possible rather than what’s wise.
  2. Is there a better way to do this than storing decorator arguments in a list?
  3. Once you’ve done a bunch of parsing and have multiple ValidationErrors in hand, what’s the correct way to combine them?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
sirosencommented, Jan 24, 2020

I worked up a version of this and concluded that it’s definitely not worth the trouble. Even if you modify use_args to put parameters into a list, which turns out not to be so bad, you have to start tinkering with the way that Parser.parse_args works too (to skip calling the error handler function).

I can get it all working, but it’s not worth making things that much messier and harder to maintain.

Assuming two, three nested calls at worse, that’s still a reasonable figure for a trial and error approach. Typically, only the body has a lot of fields.

Ultimately, this convinced me. I think you’re right.

@lafrech, thanks for taking the time to read this and talk about it. I’m going to close as a wontfix and look at other things which are worth doing for 6.0.

0reactions
lafrechcommented, Jan 21, 2020

Oh, you mean it may be too hard to let use_args do that but we could come up with another decorator that would do the two calls in one go so that we have the information about the schemas in the same decorator. Like the use_args_by_location.

Frankly, I wouldn’t bother. As I said:

I don’t see an easy way to provide all the errors at once. But it’s not a big deal if we don’t IMHO.

It’s like sometimes input data passes webargs validation and then triggers an error in the view func (e.g. unique index issue in DB), so a new error message appears.

From a security perspective, the app is covered. It’s all about client-friendliness. It’s nice to be able to return all errors from a JSON input at once rather than one by one, as the cardinality could go high. But dealing with query args first then JSON is not a big issue to me. Assuming two, three nested calls at worse, that’s still a reasonable figure for a trial and error approach. Typically, only the body has a lot of fields.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Advanced Usage - webargs 8.2.0 documentation
This section includes guides for advanced usage patterns. Custom Location Handlers#. To add your own custom location handler, write a function that receives...
Read more >
RFC: Allow a single location for each field #419 - GitHub
Combine errors from nested use_args calls so that mixed locations still provide full errors in webargs 6.x #455.
Read more >
webargs - Read the Docs
Simple, declarative syntax. Define your arguments as a mapping rather than imperatively pulling values off of request objects.
Read more >
webargs(1) - Arch manual pages
Webargs provides a consistent request-parsing interface that will work ... send these values in either location, # and they will be *mixed* together...
Read more >
Flask, Marshmallow 3, and webargs use_args fails to parse ...
Before webargs 6, the parser would iterate over the fields of the schema and, by default, search over multiple locations to find the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found