You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+PostgreSQL注册功能报Failing row contains错误排查

错误含义

Failing row contains (43, ccc, null, 0, 2022-07-01 15:37:11.631)是PostgreSQL抛出的非空约束违反错误:你向users表插入数据时,某个设置了NOT NULL(不允许为空)且无默认值的字段被传入了null,数据库拒绝写入。括号内是本次尝试插入的行数据,按你建表的字段顺序排列,对应关系为:

  • 43:自增主键id,数据库自动生成,无问题
  • ccc:用户名name,正常传入
  • null:触发报错的空值,对应email字段
  • 0:用户积分entries,建表时设置了默认值0,正常填充
  • 2022-07-01 15:37:11.631:注册时间joined,代码中传入了new Date(),无问题
根因定位

问题出在后端逻辑缺失+前后端传参不匹配,和React框架本身无关,核心问题有3个:

  • 直接触发报错的原因:插入users表时email字段值为null,要么是前端提交时漏传email参数,要么是传参格式错误导致后端未解析到email值
  • 后端注册逻辑不完整:虽然从请求体中解构了password参数,但既没有用bcrypt生成密码哈希,也没有向login表写入密码记录,就算本次约束报错修复,后续登录功能也无法正常运行
  • 错误处理缺失:接口捕获到数据库错误后仅在控制台打印,没有给前端返回错误响应,导致前端页面无反馈

另外你的App.js中渲染Register组件时,两个props之间漏了空格,会导致组件props解析异常:

// 错误写法
<Register  loadUser={this.loadUser}onRouteChange={this.onRouteChange}/>
修复步骤

1. 重写后端注册接口

替换原有/register接口代码,补全参数校验、密码哈希、事务写入、错误返回逻辑:

app.post('/register',(req,res)=>{
    const{email,name,password}=req.body;
    // 前置校验,缺参数直接返回错误,避免请求打到数据库
    if(!email || !name || !password){
        return res.status(400).json('请补全全部注册字段');
    }
    const hash = bcrypt.hashSync(password);
    // 使用事务保证users、login两张表数据一致性
    db.transaction(trx => {
        trx.insert({
            hash: hash,
            email: email
        })
        .into('login')
        .returning('email')
        .then(loginEmail => {
            return trx('users')
            .returning('*')
            .insert({
                email: loginEmail[0].email,
                name: name,
                joined: new Date()
            })
            .then(user=>{
                res.json(user[0]);
            })
        })
        .then(trx.commit)
        .catch(trx.rollback)
    })
    .catch(err => res.status(400).json('注册失败,请检查输入信息'))
})

2. 修复前端传参问题

  • 首先修正App.js中Register组件的props写法,补上空格:
<Register loadUser={this.loadUser} onRouteChange={this.onRouteChange}/>
  • 检查Register组件的提交逻辑,确保满足以下要求:

    • 请求地址为http://localhost:3000/register,不要漏写3000端口
    • 请求头添加'Content-Type': 'application/json'
    • 请求体用JSON.stringify()转换,包含email、name、password三个字段,字段名不要拼写错误

    标准提交逻辑参考:

onSubmitRegister = () => {
    fetch('http://localhost:3000/register', {
        method: 'post',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({
            email: this.state.email,
            password: this.state.password,
            name: this.state.name
        })
    })
    .then(response => response.json())
    .then(user => {
        if(user.id){
            this.props.loadUser(user)
            this.props.onRouteChange('home');
        }
    })
}

3. 校验数据库表结构

打开PostgreSQL客户端确认两张表配置正确:

  • users表:id为serial自增主键,name、email为varchar类型且设置非空约束,entries为bigint类型默认值0,joined为timestamp类型设置非空约束
  • login表:id为serial自增主键,email为varchar类型设置非空+唯一约束,hash为varchar类型设置非空约束

注:你当前的/signin、/image、/profile接口都在使用内存中的mock数据,没有操作数据库,注册功能修复后还需要同步改造这几个接口,否则登录、积分累加功能无法正常使用。

内容的提问来源于stack exchange,提问作者Ankit Dhanotia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 01:06:22