programing

Mongoose를 사용한 사용자 지정 오류 메시지

minimums 2023. 5. 23. 21:44
반응형

Mongoose를 사용한 사용자 지정 오류 메시지

따라서 mongoose 문서에 따르면 스키마에서 다음과 같은 사용자 정의 오류 메시지를 설정할 수 있어야 합니다.

 var breakfastSchema = new Schema({
  eggs: {
    type: Number,
    min: [6, 'Too few eggs'],
    max: 12
  },
  bacon: {
    type: Number,
    required: [true, 'Why no bacon?']
  }
});

그래서 저는 비슷한 것을 하고 싶었습니다.

var emailVerificationTokenSchema = mongoose.Schema({
   email: {type: String, required: true, unique: [true, "email must be unique"]},
   token: {type: String, required: true},
   createdAt: {type: Date, required: true, default: Date.now, expires: '4h'}
});

이러한 토큰 중 하나를 저장하려고 하면 이미 충돌하는 토큰이 있을 때 "이메일은 고유해야 합니다"라는 오류 메시지가 표시됩니다.

그러나 다음과 같은 작업을 수행할 때(같은 전자 메일로 토큰을 저장하는 경우):

verificationToken.save( function (err) {
    if (err) {
      return console.log(err);
    }
    else {
      return console.log(err);
    }
});

계속 이해가 되네요.

'E11000 duplicate key error: index ___.emailVerificationToken.$email_1 dup key: { : "_____@wdad.com

무슨 생각 있어요?사용자 지정 메시지에 대해 고유 매개 변수가 지원되지 않습니까?이것이 일을 진행하는 실행 가능한 방법입니까?

사용자 지정 메시지에 대해 고유 매개 변수가 지원되지 않습니까?

Mongoose의 고유성은 유효성 매개 변수가 아닙니다(예:requiredMongoose에 해당 필드에 대한 고유 인덱스를 MongoDB에 생성하도록 지시합니다.

고유 제약 조건은 전적으로 MongoDB 서버에서 처리됩니다.중복 키가 있는 문서를 추가하면 MongoDB 서버는 사용자가 표시하는 오류를 반환합니다.E11000...).

사용자 지정 오류 메시지를 만들려면 이러한 오류를 직접 처리해야 합니다.Mongoose 설명서("Error Handling Middleware")는 사용자 정의 오류 처리를 만드는 방법에 대한 예를 제공합니다.

emailVerificationTokenSchema.post('save', function(error, doc, next) {
  if (error.name === 'MongoError' && error.code === 11000) {
    next(new Error('email must be unique'));
  } else {
    next(error);
  }
});

(단, 고유성 제약 조건이 실패한 특정 필드는 제공되지 않습니다.)

시도한 것처럼 직접적으로 가능한 것은 아니지만 고유성이 침해될 경우 사용자 지정 오류 메시지를 허용하는 mongoose-unique-validator를 확인해야 할 수 있습니다.

특히 사용자 지정 오류에 대한 섹션은 사용자가 관심을 가져야 합니다.

원하는 것을 얻기 위해

"이메일은 고유해야 함"

이것과 비슷하게 보일 것입니다.

var uniqueValidator = require('mongoose-unique-validator');
...
emailVerificationTokenSchema.plugin(uniqueValidator, { message: '{PATH} must be unique' });
verificationToken.save( function (err) {
    if (err) {
      return res.status(400).send({
          message: (err.name === 'MongoError' && err.code === 11000) ? 'Email already exists !' : errorHandler.getErrorMessage(err)
      });
    }
    else {
      return console.log('No Error');
    }
  });

Schema의 고유한 값에 대한 오류 메시지는 실제로 사람에게 친숙하지 않습니다.이것은 저를 매우 방해했지만, 제가 에러 오브젝트에 남아있는 키를 보았을 때, 저는 이것을 장치할 수 있었습니다.

오류 메시지를 반환할 때

 document.save().then(() => {
        return res.status(201).json({
          statusText: "created",
          message: "document created successfully",
          data: brand,
        });
      })
      .catch((error) => {

        // Set custom error for unique keys
        let errMsg;
        if (error.code == 11000) {
          errMsg = Object.keys(error.keyValue)[0] + " already exists.";
        } else {
          errMsg = error.message;
        }
        res.status(400).json({ statusText: "Bad Request", message: errMsg });
      });

모든 답변 감사합니다, 저는 제 문제를 이해했습니다.

제 스키마는 이렇습니다.

var User = new Schema({
  username: {type: String, required: [true, "Username is required"], unique: true},
  email: {type: String, required: [true, "Email is required"], unique: true},
  password: {type: String, required: true, unique: false},
});

기능처럼 사용하는 것을 추천합니다.

이렇게 사용할 수 있습니다.

User.post("save", function (error, doc, next) {

  if (error.keyValue.email != null && error.name === "MongoError" && error.code === 11000) {

    console.log("Email must be unique");
  } else if (error.keyValue.username != null && error.name === "MongoError" && error.code === 11000) {
    console.log("Username must be unique");
  } else {
    console.log("not found any idea, search for another reasons");
  }
});

Mongoose 5.x.x용 업데이트된 버전

MySchema.post('save', function (error, doc, next) {
    if (err.name === 'BulkWriteError' && error.code === 11000) 
        next(new Error('This item already exists, please try again'));
    else next(error);
});

그냥 미들웨어를 바르세요.

recordingSchema.post('save', function (error, _, next) {
    next( error.code === 11000 
      ?   new Error('This item field already exist')
      :   error)
});

사용자 지정 비동기식 검증기를 추가할 수 있습니다.예:

 {
      validator: (value) => {
        return UserModel.findOne({ email: value })
          .then(user => Promise.resolve(user == null))
          .catch(error => Promise.reject(false));
      },
      message: "User with this email already exists"
 }

제가 처리하는 방법은 다음과 같습니다.

schema.post('save', function (error, doc, next) {
    let errorMessage

    // map with all unique items you defined in your schema 
    const errorsMap = {
        email: 'your message for existing email',
        otherUniqueItem: 'your message for existing item',
    }

    if (error.code === 11000) {
        errorMessage = Object
            .keys(error.keyValue)
            .map(key => errorMap[key])
            .join(', ')
    } else {
        errorMessage = error.message
    }

    if (errorMessage) next(new Error(errorMessage))
    else next()
})

업데이트된 mongoose 버전 5.x.x에서는 이 특정 요구 사항을 지원합니다.

https://mongoosejs.com/docs/middleware.html#error-handling-middleware

스키마에 대한 게시 방법을 추가하여 다음과 같이 수행할 수 있습니다. // 사용자 저장 후 사용자가 중복되면 오류를 반환합니다.

userSchema.post('save', function(error: any, doc: any, next: any) {
  if (error.name === 'MongoError' && error.code === 11000) {
    next(new Error('user_exists'));
  } else {
    next();
  }
});

unique는 검증자가 아니므로 이 시나리오에 대한 스키마에 사용자 지정 오류가 있을 수 없습니다.그러나 고유성을 확인하는 또 다른 방법은 exists() 메서드를 사용하는 것입니다.예:

const User = require('/path/to/model')

app.post('/route-name', async (req, res) => {
  // destructure the request body 
  const { email, password } = req.body;
  
  // Assuming you have an email property in your user model, we check if the email in the request body exists in the database
  // This can take multiple fields as well.
  const exists = await User.exists({ email: email });
  if (exists) return res.json({ error: 'email exists' });
  
  // rest of your logic if email doesn't exist
});

언급URL : https://stackoverflow.com/questions/38945608/custom-error-messages-with-mongoose

반응형