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

Server error when throw exception in beforeSave hook #5063

Closed
reallyimeric opened this issue Sep 19, 2018 · 9 comments
Closed

Server error when throw exception in beforeSave hook #5063

reallyimeric opened this issue Sep 19, 2018 · 9 comments

Comments

@reallyimeric
Copy link
Contributor

Issue Description

I tried to abort a save action in beforeSave hook, following instruction, and got http 500 for this request.

Steps to reproduce

Parse.Cloud.beforeSave('Master', async (req) => {
    throw new Error('cya');
});

then update a Master object using the dashboard or js client.

Expected Results

client got an error with message cya.

Actual Outcome

client got body {"code":1,"message":"Internal server error."} with http code 500.
After that client tried 4 more times and then gave up.

Environment Setup

  • Server

    • parse-server version (Be specific! Don't say 'latest'.) : 3.0.0
    • Operating System: linux
    • Hardware: x86_64
    • Localhost or remote server? (AWS, Heroku, Azure, Digital Ocean, etc): localhost
  • Database

    • MongoDB version: mongodb 3.6.5 WiredTiger: 3.0.1: (January 8, 2018)
    • Storage engine: wiredtiger
    • Hardware: the same with server
    • Localhost or remote server? (AWS, mLab, ObjectRocket, Digital Ocean, etc): the same with server

Logs/Trace

error: beforeSave failed for Master for user undefined:
  Input: xxxxxxxx... (truncated)
  Error: {} className=Master, triggerType=beforeSave, , user=undefined
error: Uncaught internal server error. Error: cya
    at _callee$ (/home/xxxxx/src/parse/cloud.js:7:11)
    at tryCatch (/home/xxxxx/node_modules/regenerator-runtime/runtime.js:62:40)
    at Generator.invoke [as _invoke] (/home/xxxxx/node_modules/regenerator-runtime/runtime.js:296:22)
    at Generator.prototype.(anonymous function) [as next] (/home/xxxxx/node_modules/regenerator-runtime/runtime.js:114:21)
    at step (/home/xxxxx/node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
    at /home/xxxxx/node_modules/babel-runtime/helpers/asyncToGenerator.js:35:14
    at new Promise (<anonymous>)
    at new F (/home/xxxxx/node_modules/core-js/library/modules/_export.js:35:28)
    at /home/xxxxx/node_modules/babel-runtime/helpers/asyncToGenerator.js:14:12
    at /home/xxxxx/src/parse/cloud.js:5:1
    at Promise.resolve.then (/home/xxxxx/node_modules/parse-server/src/triggers.js:438:23)
    at process._tickCallback (internal/process/next_tick.js:68:7) Error: cya
    at _callee$ (/home/xxxxx/src/parse/cloud.js:7:11)
    at tryCatch (/home/xxxxx/node_modules/regenerator-runtime/runtime.js:62:40)
    at Generator.invoke [as _invoke] (/home/xxxxx/node_modules/regenerator-runtime/runtime.js:296:22)
    at Generator.prototype.(anonymous function) [as next] (/home/xxxxx/node_modules/regenerator-runtime/runtime.js:114:21)
    at step (/home/xxxxx/node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
    at /home/xxxxx/node_modules/babel-runtime/helpers/asyncToGenerator.js:35:14
    at new Promise (<anonymous>)
    at new F (/home/xxxxx/node_modules/core-js/library/modules/_export.js:35:28)
    at /home/xxxxx/node_modules/babel-runtime/helpers/asyncToGenerator.js:14:12
    at /home/xxxxx/src/parse/cloud.js:5:1
    at Promise.resolve.then (/home/xxxxx/node_modules/parse-server/src/triggers.js:438:23)
    at process._tickCallback (internal/process/next_tick.js:68:7)
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:470:11)
    at ServerResponse.header (/home/xxxxx/node_modules/parse-server/node_modules/express/lib/response.js:767:10)
    at ServerResponse.send (/home/xxxxx/node_modules/parse-server/node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/home/xxxxx/node_modules/parse-server/node_modules/express/lib/response.js:267:15)
    at errorHandler (/home/xxxxx/src/errorHandler.js:4:24)
    at Layer.handle_error (/home/xxxxx/node_modules/express/lib/router/layer.js:71:5)
    at trim_prefix (/home/xxxxx/node_modules/express/lib/router/index.js:315:13)
    at /home/xxxxx/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/home/xxxxx/node_modules/express/lib/router/index.js:335:12)
    at next (/home/xxxxx/node_modules/express/lib/router/index.js:275:10)
    at Layer.handle_error (/home/xxxxx/node_modules/express/lib/router/layer.js:67:12)
    at trim_prefix (/home/xxxxx/node_modules/express/lib/router/index.js:315:13)
    at /home/xxxxx/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/home/xxxxx/node_modules/express/lib/router/index.js:335:12)
    at next (/home/xxxxx/node_modules/express/lib/router/index.js:275:10)
    at Layer.handle_error (/home/xxxxx/node_modules/express/lib/router/layer.js:67:12)
@flovilmart
Copy link
Contributor

What version of node are you using? And why is your stacktrace riddled with regenerator runtime calls?

@reallyimeric
Copy link
Contributor Author

@flovilmart node version is v10.10.0. I'm using babel.

This is my gulpfile:

const gulp = require('gulp');
const babel = require('gulp-babel');
const nodemon = require('gulp-nodemon');
const del = require('del');
const mocha = require('gulp-mocha');

gulp.task('default', () => {
    nodemon({
        script: 'src/index.js',
        execMap: {
            js: 'node_modules/.bin/babel-node --presets env --plugins transform-runtime,transform-object-rest-spread,transform-class-properties --inspect',
        },
        debug: true,
        ext: 'js',
        env: { NODE_ENV: 'development' },
        ignore: [
            'dist/',
        ],
    });
});

gulp.task('build', ['clean'], () => gulp.src('src/**/*.js')
    .pipe(babel({
        presets: ['env'],
        plugins: ['transform-runtime', 'transform-object-rest-spread', 'transform-class-properties'],
    }))
    .pipe(gulp.dest('dist')));

gulp.task('clean', () => del([
    'dist/**',
]));

gulp.task('test', () => gulp.src('test/test.js', { read: false })
    .pipe(mocha()));

I'm using babel-node in dev.

@flovilmart
Copy link
Contributor

@reallyimeric this is working fine in our tests: https://github.com/parse-community/parse-server/blob/803c6d2/spec/CloudCode.spec.js#L54

Both on node 8 and node 10. You should probably not use transform-runtime nor babel as it's clearly producing some code that doesn't work.

@flovilmart
Copy link
Contributor

my bad, this is actually yielding the same issue as yours, use return Promise.reject(); or throw new Parse.Error(-1, 'My Error') you can replace -1 with the error code of your choice.
Even better, you can open a PR with the potential fix.

@reallyimeric
Copy link
Contributor Author

reallyimeric commented Sep 19, 2018

I have submitted a pr. By the way, return Promise.reject(); leads to a response of http 401 parse server middleware passing control to the next express middleware (return 401 for my instance).

@flovilmart
Copy link
Contributor

This should be resolved with your fix no? Depending on the type inside the rejection. If you don’t pass anything, then it’s probably what you’re experiencing. Do you happen to have logs for this?

@reallyimeric
Copy link
Contributor Author

Yes it was. I have not digged into that before.

@jeremypiednoel
Copy link
Contributor

Hi Guys I have the same issue, Thanks @reallyimeric for the fix.
Do you guys know when it will be released ?
Thanks.

@acinader
Copy link
Contributor

fixed by #5064

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants