nonoom
nonoom

Reputation: 344

TypeError: res.status is not a function

I'm making a function that permits me to upload a picture to imgur in my express API (nodejs), I'm encountering an error when calling a function returning a promise:

TypeError: res.status is not a function
at uploadpicture.then

This is my code: Where error is raised:

  router.post('/upload', (req, res, next)=> { 
    var busboy = new Busboy({headers: req.headers});
    busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
        if(fieldname == 'image') {
            // the buffer
            file.fileRead = [];
            file.on('data', function(data) {
                // add to the buffer as data comes in
                this.fileRead.push(data);
            });

            file.on('end', function() {
                // create a new stream with our buffered data
                var finalBuffer = Buffer.concat(this.fileRead);
                upload = uploadpicture(finalBuffer).then((res)=>{ //success request
                  console.log(res);
                  res.status(200).json({success: true, message: "Successfully uploaded !", url: res.data.link});
                },(err)=>{ //error
                  res.status(500).json({success: false, message: "Error happenned while uploading !"});
                }).catch((error)=>{
                  console.log(error);
                  res.status(500).json({success: false, message: "Error happenned while uploading !"});
                });

            })
        }
    });
    busboy.on('finish', function() {
        //busboy finished
    });
    req.pipe(busboy);
});

And the function :

function uploadpicture(stream){ //get picture stream
    return new Promise((resolve, reject)=>{
    var options = {
      uri: 'https://api.imgur.com/3/image',
      method: 'POST',
      headers: {
          //'Authorization': 'Client-ID ' + config.client_id_imgur // put client id here
      },
      formData: {
          image: stream,
          type: 'file'
      },
      auth: {
        bearer: config.access_token_imgur,
      }
  };
  
  request(options)
      .then((parsedBody)=> {
          resolve(parsedBody);
      })
      .catch((err)=> {
        console.log(err);
        reject(err.toString())
      });
    });
  }
   

The code works perfectly, but I don't know why suddenly this error happened, I tried to:

change arrow functions to function(){}
Add next to the route parameters

Nothing worked.

Upvotes: 30

Views: 101395

Answers (9)

Maksudul ISlam
Maksudul ISlam

Reputation: 1

Here's the thing:

the order of (req,res,next) really matters.

In my case the problem was just the order. For example if I want to get user info:

export const getUserInfo = async(res:Response,req:Request,next:NextFunction) => {
try {
    const userId = await req.user 
    const user = await userModel.findById(userId);

res.status(200).json({
    success: true,
    user,
})


} catch (error:any) {
    return next(new ErrorHandler(error.message,400))
}

here I used:

  1. req first
  2. Then I used res

Which was the problem. after switching them on function parameters everything works fine.

Upvotes: 0

kakopappa
kakopappa

Reputation: 5085

Root cause is

Error-handling middleware always takes four arguments. You must provide four arguments to identify it as an error-handling middleware function. Even if you don’t need to use the next object, you must specify it to maintain the signature. Otherwise, the next object will be interpreted as regular middleware and will fail to handle errors.

In my case, I had enabled ES-Lint and it warned me about unused next so I removed it... Later on in the production logs started seeing this error. so do not forget to add this to lint ignore list.

// eslint-disable-next-line no-unused-vars
app.use((err, req, res, next) => {
})

Upvotes: 1

Satish Gadde
Satish Gadde

Reputation: 81

You are getting this error:

TypeError: res.status is not a function

Because the order should be (err, req, res, next) not (req, res, err, next), example below

const errorHandler = (err, req, res, next) => {
    const statusCode = res.statusCode === 200 ? 500 : res.statusCode;
    res.status(statusCode)
    res.json({
        message : err.message,
        stack :process.env.NODE_ENV === 'production' ? null : err.stack, 
    })
}

Upvotes: 8

netrolite
netrolite

Reputation: 2703

I was setting the type of req and res to Request and Response, respectively, without actually importing these types from Express!

Upvotes: -1

Iasonas Christoulakis
Iasonas Christoulakis

Reputation: 37

I had the same issue. I resolved it by change the order of functions (req,next,res) to (req,res,next). May it needs them in a strict order to call them properly!

Upvotes: 0

Ethan Miles
Ethan Miles

Reputation: 1

If you are using the async/await method:

const notifications = await notifications.aggregate({...})
if(notifications){
  return res.status(200).json({ data: notifications })
}else{
  return res.status(404).json({ message: 'No notifications found'})
}

Make sure that you are including your return statements. Not including a return statement will cause this. Something else that I was doing is I had JSON instead of json, which will most definitely throw an error.

Upvotes: 0

smit agravat
smit agravat

Reputation: 295

Order of parameters really matters i had error in below code

const getImagesByBrand = async (res) => {
  try {
    const images = await Image.find();
    res.status(200).json(images);
  } catch (error) {
    res.status(500).json(error);
  }
};

I was not giving req as parameter and that was the reason for error i just add req,res and it worked

Upvotes: -2

user16435030
user16435030

Reputation:

The accepted answer directly addresses the OP's problem, but I post another solution since you can also encounter this error in other places.

When you have:

api.use((error: ErrorRequestHandler, request: ExpressRequest, response: ExpressResponse) => {
  response.status(500).end() // response.status is not a function
})

Because the error handling route must accept 4 arguments for express to identify it as an error middleware.

api.use((error: ErrorRequestHandler, request: ExpressRequest, response: ExpressResponse, next: NextFunction) => {
  response.status(500).end()
})

Just adding the next function (or whatever argument you're missing) will fix it.

https://github.com/visionmedia/supertest/issues/416#issuecomment-514508137

Upvotes: 47

Luiz Fernando da Silva
Luiz Fernando da Silva

Reputation: 1499

At this point:

upload = uploadpicture(finalBuffer).then((res)=>{ //success request

the resis the result of promise uploadpicture function (that is the parsedBody), not the res from the express route. So indeed, it has no status function. Try change the then callback name like:

upload = uploadpicture(finalBuffer).then((otherName)=>{ //success request

Upvotes: 20

Related Questions