2

How would you recommend as the best approach / UX for sharing with a customer the REST API errors in their nested JSON body? Say for example they are to send an object with 30 fields, but they only send 24 fields, and of the 24, 3 are unknown field names, and 5 are the incorrect data type. How would you like to see that error?

For example, if I have a data type sort of like this:

{
  a: number
  b: {
    x: number
    y: boolean
  }
}

And I try to validate with this data:

{
  a: 'foo'
}

I get this set of errors with zod:

[
  {
    "code": "invalid_type",
    "expected": "number",
    "received": "string",
    "path": [
      "a"
    ],
    "message": "Expected number, received string"
  },
  {
    "code": "invalid_type",
    "expected": "object",
    "received": "undefined",
    "path": [
      "b"
    ],
    "message": "Required"
  }
]

If I give it:

{ a: 'foo', b: { x: true } }

I get:

[
  {
    "code": "invalid_type",
    "expected": "number",
    "received": "string",
    "path": [
      "a"
    ],
    "message": "Expected number, received string"
  },
  {
    "code": "invalid_type",
    "expected": "number",
    "received": "boolean",
    "path": [
      "b",
      "x"
    ],
    "message": "Expected number, received boolean"
  },
  {
    "code": "invalid_type",
    "expected": "boolean",
    "received": "undefined",
    "path": [
      "b",
      "y"
    ],
    "message": "Required"
  }
]

Is this as good as it gets? Is there a better way to gather and present the errors in JSON form like this? I like this, but it for some reason still feels hard to understand and you have to really think about it to see the problem. Maybe there is a simpler way.

5
  • 1
    You should focus on how to help users when errors occur, not on error messages from the server. So the code is irrelevant but context is key. Since there is no context given I voted to close the question as being too vague.
    – jazZRo
    Jun 4, 2023 at 10:44
  • 1
    you have all the information in the json. How you present it to the user is not related. How is this a UX question?
    – njzk2
    Jun 4, 2023 at 21:05
  • "How would you like to see that error?" - are you asking about the API design part here, or are you asking how some client should best present this info in a user interface?
    – Bergi
    Jun 4, 2023 at 22:10
  • @Bergi How a client should present this info in the terminal (or in the web console/inspector). Basically a text interface UX.
    – Lance
    Jun 5, 2023 at 0:19
  • 1
    Since it indirectly impacts display and provides hints about info grouping, it's worth noting that there is a proposed standard for error responses returned from a REST API: datatracker.ietf.org/doc/html/rfc7807
    – Tim M.
    Jun 5, 2023 at 16:49

2 Answers 2

5

Given that you'll have developers and potentially QA seeing this error, you want to show only the basics first (i.e. the property path and the message). This should be enough to let whoever's seeing the error know what's wrong and how to fix it.

Hide the complete JSON in a drop-down if possible. I say this because you want to avoid too much scanning (this is why you feel "off" about the current state of the JSON, lots of scanning is the quickest way to make sure a ticket comes back from QA or UAT).

As for the multiple errors situation, you want to stack the errors over each other.

Given this error JSON:

[
  {
    "code": "invalid_type",
    "expected": "number",
    "received": "string",
    "path": [
      "a"
    ],
    "message": "Expected number, received string"
  },
  {
    "code": "invalid_type",
    "expected": "number",
    "received": "boolean",
    "path": [
      "b",
      "x"
    ],
    "message": "Expected number, received boolean"
  },
  {
    "code": "invalid_type",
    "expected": "boolean",
    "received": "undefined",
    "path": [
      "b",
      "y"
    ],
    "message": "Required"
  }

You should see something like this:

a: Expected number, received boolean;
b/x: Expected number, received boolean;
b/y: [REQUIRED] Expected boolean, received undefined;

▶ Click to view error object

[Added on 4 Jun '23 22:52] Also using dot notation for complex property paths:

a: Expected number, received boolean;
b.x: Expected number, received boolean;
b.y: [REQUIRED] Expected boolean, received undefined;

▶ Click to view error object

Also, quick note, if the error object's message is "Required", I've used a different format to better communicate the issue: ${path}: [REQUIRED] Expected ${expected}, received ${received}.

2
  • 1
    Very nice, I like it a lot! Instead of having the property be left with a colon, how about making a tree of some sort, so it can handle long property paths nicely? Wondering what your take on that would be like. Also I am mainly thinking about doing this in the terminal (I should have mentioned), so probably no dropdown functionality.
    – Lance
    Jun 4, 2023 at 19:57
  • 1
    @Lance happy to be of some service. As for your request, you should have definitely mentioned that this was a CLI tool. Though, I guess your question would have received way less attention. But anywho, personally I'm not a fan of seeing objects in my console logs. Though if you really want to, then use chalk/colors (I'm assuming you are using nodejs) to emphasize the import bits. But I still need to mention, please avoid using tree structures, maybe try instead dot notation (answer updated) Jun 4, 2023 at 20:49
3

I like this, but it for some reason still feels hard to understand and you have to really think about it to see the problem.

You always have to keep your audience in mind. In this case, that's not typical end users, but software developers (maybe not the type that writes code, but at least people who are used to analytical problem solving). What we value most is accurate information that helps us solving the problem with the least amount of digging. This format is a bit verbose, I'm used to what the library we use to validate JSON Schema (I forgot its name) produces, something like

Message: Invalid type. Expected Array but got String.
Schema path: #/properties/type/anyOf/1/type

But I wouldn't mind; it's my responsibility as the client-side developer to send a valid request, and if you provide good documentation that should be doable.

FWIW, a typical stack trace is harder to understand, but still helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.