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

Batch input validation not working as expected #10174

Open
wieseljonas opened this issue Mar 21, 2024 · 1 comment
Open

Batch input validation not working as expected #10174

wieseljonas opened this issue Mar 21, 2024 · 1 comment
Labels
k/bug Something isn't working

Comments

@wieseljonas
Copy link

Version Information

Server Version: v2.33.4
CLI Version (for CLI related issue):

Environment

Local Docker

What is the current behaviour?

When inserting batch objects only the first one gets validated:

mutation InsertUsers($users: [users_insert_input!]!) {
  insert_users(
    objects: $users
  ) {
    affected_rows
    returning {
      full_name
      phone_numbers {
        number
      }
    }
  }
}

Here below it fails as expected as the first number is not valid

{
  "users": [
    {
      "imported_id": "1247775",
      "first_name": "Pozzi",
      "last_name": "",
      "emails": {
        "data": [
          {
            "email": "mariefoti@bluewin.ch"
          }
        ]
      },
      "phone_numbers": {
        "data": [
         
          {
            "number": "764881022",
            "primary": true
          },
          {
            "number": "+41700081022",
            "primary": true
          }
        ]
      },
      "language": "fr",
      "home_address_route": "",
      "home_address_postcode": "",
      "home_address_locality": "",
      "home_address_country_code": ""
    }
  ]
}

Here below it passes with not errors and inserts both numbers in the db. The second one bypasses validation

If I insert more than 1 user in only validate 1st number of 1st user

{
  "users": [
    {
      "imported_id": "1247775",
      "first_name": "Pozzi",
      "last_name": "",
      "emails": {
        "data": [
          {
            "email": "mariefoti@bluewin.ch"
          }
        ]
      },
      "phone_numbers": {
        "data": [
          {
            "number": "+41700081022",
            "primary": true
          },
          {
            "number": "764881022",
            "primary": true
          },
        ]
      },
      "language": "fr",
      "home_address_route": "",
      "home_address_postcode": "",
      "home_address_locality": "",
      "home_address_country_code": ""
    }
  ]
}

What is the expected behaviour?

It should validate all phone numbers

How to reproduce the issue?

  1. create an input validation
  2. try inserting n+1 objects

Screenshots or Screencast

Please provide any traces or logs that could help here.

Any possible solutions/workarounds you're aware of?

Keywords

@wieseljonas wieseljonas added the k/bug Something isn't working label Mar 21, 2024
@wieseljonas
Copy link
Author

so it was error in validation function

it was only validating the first object. now it works but I'm unable to return the path of which object fails

import { createQuery, graphql } from '../../utils/hasura-client.js';
import { parsePhoneNumberFromString } from 'libphonenumber-js';
import type { Request, Response } from 'express';
import { phoneNumberIsCallingCodeAllowedQuery } from './__generated__/phoneNumberIsCallingCodeAllowedQuery.graphql.js';

const isCallingCodeAllowed =
  createQuery<phoneNumberIsCallingCodeAllowedQuery>(graphql`
    query phoneNumberIsCallingCodeAllowedQuery($country_code: String!) {
      countries(
        where: {
          phone_number_allowed: { _eq: true }
          country_code: { _eq: $country_code }
        }
      ) {
        country_code
      }
    }
  `);

export const post = async (req: Request, res: Response) => {
  const errors: {
    message: string;
    extensions: { path: string; code: string };
  }[] = [];

  const data = req.body.data.input;

  console.log('data', data);

  // loop through the data and validate each phone number

  data.forEach(async (input: { number: string }, index: number) => {
    const { number } = input;

    const phoneNumber = parsePhoneNumberFromString(number ?? '');
    if (!phoneNumber?.isValid()) {
      errors.push({
        message: 'The phone number is invalid',
        extensions: {
          path: `$.number`,
          code: 'validation-failed',
        },
      });
    }

    // Check if number country is allowed
    const allowedCountries = await isCallingCodeAllowed({
      country_code: phoneNumber?.country ?? '',
    });

    if (allowedCountries.countries.length === 0) {
      errors.push({
        message: 'The phone number country is not allowed',
        extensions: {
          path: `$.input[${index}].number`,
          code: 'validation-failed',
        },
      });
    }
  });

  console.log('errors', errors);
  if (errors.length > 0) {
    return res.status(400).json(errors[0]);
  }

  return res.status(200).send('OK');
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
k/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant