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

validation error broken? maybe related to serverless-offline / serverless-webpack plugin? #94

Closed
dwelch2344 opened this issue Jan 19, 2018 · 7 comments

Comments

@dwelch2344
Copy link

Just getting started and can't seem to get validation error messages working based on the README. We're using the es7 webpack plugin + serverless-offline, but I don't think that is why.

No matter what we do, we always get a strange Unexpected 'E' response body.

Tried debugging, going as far to the actual source and making sure all our middleware is hit in the correct order and everything, but no dice.

Anyone able to take a look at / spot a stupid mistake we're making? Thanks in advance

handler.js

const middy = require('middy')
const { urlEncodeBodyParser, validator, httpErrorHandler, cors, jsonBodyParser } = require('middy/middlewares')

const dummy = (event, context, callback) => callback(
  { statusCode: 200, body: JSON.stringify({message: 'hi'})}
)
const demo = middy( dummy )
  .use(urlEncodeBodyParser()) // parses the request body when it's a JSON and converts it to an object
  .use(validator({inputSchema})) // validates the input
  .use(httpErrorHandler()) // handles common http errors and returns proper responses

module.exports = { demo }

serverless.yml

# NOTE: update this with your service name
service: demo

# Use the serverless-webpack plugin to transpile ES6
plugins:
  - serverless-webpack
  - serverless-offline


# Enable auto-packing of external modules
custom:
  webpackIncludeModules: true
  stage: "${opt:stage, self:provider.stage}"

provider:
  name: aws
  runtime: nodejs6.10
  stage: dev
  region: us-east-1

functions:
  demo:    
    handler: handler.demo
    events:
      - http:
          cors: true
          path: demo/
          method: POST    
@vladholubiev
Copy link
Contributor

Is this what you're talking about 🤔

#64

@dwelch2344
Copy link
Author

@vladgolubev Yes, thank you! Just tried the example middleware from the first post and it gave me more of what I expected.

I had skimmed the issue and comments but missed the little line with my error message. Fried from a long day at work but I'll review that thread in detail tomorrow. Thanks again :)

@lmammino
Copy link
Member

Hello @dwelch2344, thanks for your submission.

Since you are the second person affected by this, I was trying to spend some time yesterday to replicate your issue and investigate it further, but I wasn't able to reproduce the case.

I'd like to see your full code implementation (the one you posted seems more like a draft rather than the real implementation). Would you be ok with posting it?

@andrewfluck
Copy link

I have this error too when using serverless-offline-plugin, and can reproduce with his code

@andrewfluck
Copy link

Infact, it does this in AWS as well, it sends a plaintext message, not a JSON string

@andrewfluck
Copy link

andrewfluck commented Aug 26, 2018

This is my implementation, its not perfect, I still need to go through things...

const inputSchema = {
    required: [ 'name', 'email', 'password' ],
    properties: {
        name: { type: 'string' },
        email: { type: 'string', pattern: '/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/' },
        password: { type: 'string' },
    },
};

const userCreate = async (evt, ctx) => {
    ctx.callbackWaitsForEmptyEventLoop = false;
    let { name, email, password } = evt.body;

    const salt = await bcrypt.genSalt();
    const hash = await bcrypt.hash(password, salt);
    password = hash;

    try {
        mongoose.connect(MONGO_URL);
    } catch (err) {
        return { statusCode: 501, body: JSON.stringify({ message: err || 'Internal server error.' })};
    }

    try {
        const userExists = await UserModel.find({ email }).limit(1);

        if (userExists.length === 0) {
            const newUser = new UserModel({ ...body, salt });
            await newUser.save();
            mongoose.connection.close();

            return { statusCode: 200, body: JSON.stringify({ name, email })};
        } else {
            return { statusCode: 404, body: JSON.stringify({ message: 'User exists' })};
        }
    } catch (err) {
        mongoose.connection.close();
        return { statusCode: 501, body: JSON.stringify({ message: err || 'Internal server error.' })};
    }
};

const handler = middy(userCreate)
    .use(validator({ inputSchema }))
    .use(urlEncodeBodyParser())
    .use(httpErrorHandler());

module.exports = { handler };

@andrewfluck
Copy link

I've done some digging around, this is an issue caused by httpsErrorHandler middleware. Its an easy fix. Give the option to switch between a JSON error, or a plain-text body. For now I will make my own error solution that is similar to that of httpErrorHandler.

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

No branches or pull requests

4 participants