skip to Main Content

I keep getting an unhandled promise rejection error from my server as soon as I add any code to a specific resolver of mine used to query and mutate data in MongoDB. The code for the resolver is as shown:

import { Coordinates, Fridge, Fridges } from '../models/Fridge';
import { Arg, Ctx, Field, InputType, Mutation, Resolver } from 'type-graphql';
import { MyContext } from '../types';
import { Users } from '../models/User';

@InputType()
class FridgeInput {
  @Field()
  name: string

  @Field()
  address: string

  @Field()
  description: string

  @Field(() => Coordinates)
  coordinates?: Coordinates
}

@Resolver()
export class FridgeResolver {
  @Mutation(() => Fridge)
  async createFridge (
    @Arg("inputs") inputs: FridgeInput,
    @Ctx() { req } : MyContext
  ): Promise<Fridge | undefined> {
      const author = Users.findOne({_id: req.session.userId});
      const {name, address, description, coordinates} = inputs;
  
      const fridge = new Fridges({
        name,
        address,
        description,
        author,
        coordinates: coordinates ? coordinates : undefined
      })
  
      try {
        await fridge.save()
      } catch (error) {
        console.log(error)
        return undefined
      } 
    
      return fridge
  }
}

I am trying to reference other classes in the Fridges class and wasn’t sure if I was doing that right but I couldn’t imagine how that would be the root of the problem. The code for this is here:

import { Field, ID, ObjectType } from "type-graphql";
import { prop, getModelForClass, Ref } from "@typegoose/typegoose";
import { User } from './User';

export class Coordinates {
  lat: number
  lng: number
}

@ObjectType()
export class Fridge {
  @Field(() => ID, {nullable: true})
  _id: string

  @Field() 
  @prop({required: true})
  name: string;

  @Field() 
  @prop({required: true})
  address: string;

  @Field() 
  @prop({required: true})
  description: string;

  @Field(() => User, {nullable: true}) 
  @prop({required: true, ref: User})
  public author: Ref<User>

  @Field(() => Coordinates, {nullable: true}) 
  @prop({required: true})
  cordinates?: Coordinates;
};

export const Fridges = getModelForClass(Fridge);

Lastly here is the code for my server:

***** As soon as I remove the FridgeResolver the error goes away. Also if I remove all the code within the FridgeResolver but leave it in the ApolloServer it also goes away. ********

import { ApolloServer } from "apollo-server-express";
import "colors";
import connectRedis from "connect-redis";
import cors from 'cors';
import express from "express";
import session from "express-session";
import Redis from "ioredis";
import mongoose from "mongoose";
import "reflect-metadata";
import { buildSchema } from "type-graphql";
import { COOKIE_NAME, __prod__ } from "./constants";
import { FridgeResolver } from './resolvers/fridge';
import { HelloResolver } from "./resolvers/hello";
import { UserResolver } from "./resolvers/user";

// create express instance:
const app = express();
// connect to our mongo database
const connectDB = async() => {
  try {
    const conn = await mongoose.connect('mongodb://localhost:27017/cff', {
      useNewUrlParser: true,
      useCreateIndex: true,
      useUnifiedTopology: true,
      useFindAndModify: false,
      autoIndex: true
    });
    console.log(`Mongo Connected to: ${conn.connection.host}`.cyan.bold)
  } catch (error) {
    console.log(`Error: ${error}`.red.bold);
    process.exit();
  }
};

connectDB();
const main = async () => {
  // Redis 
  const RedisStore = connectRedis(session);
  const redis = new Redis();
  // cors 
  app.use(cors({
    origin: 'http://localhost:3000',
    credentials: true,
  }));
  // Session middleware needs to come before apollo so we can use it inside apollo middleware
  app.use(
    session({
      name: COOKIE_NAME,
      store: new RedisStore({
        client: redis, 
        disableTouch: true,
      }),
      cookie: {
        maxAge: 1000 * 60 * 60 * 24 * 365 * 10, // 10 years
        httpOnly: true,
        sameSite: 'lax',
        secure: __prod__, // cookie only works in https 
      },
      secret: '123',
      resave: false,
      saveUninitialized: false,
    })
  );

  // Apollo server
  const apolloServer = new ApolloServer({
    schema: await buildSchema({
      resolvers: [HelloResolver, UserResolver, FridgeResolver],
      validate: false,
    }),
    context: ({ req, res }) => ({ req, res, redis })
  })
  apolloServer.applyMiddleware({ app, cors: false });
  const PORT = 4000;
  app.listen(PORT, ()=> {
    console.log(`Server is listening on port ${PORT}`.blue.bold)
  });
};

main().catch((err) => {
  console.log(err.red.bold)
});

2

Answers


  1. Chosen as BEST ANSWER

    I was able to get rid of the error by changing the fields in my Fridge class to:

    import { Field, Float, ID, ObjectType } from "type-graphql";
    import { prop, getModelForClass, Ref } from "@typegoose/typegoose";
    import { User } from './User';
    
    @ObjectType()
    export class Fridge {
      @Field(() => ID, {nullable: true})
      _id: string
    
      @Field(() => String) 
      @prop({required: true})
      name: string;
    
      @Field(() => String) 
      @prop({required: true})
      address: string;
    
      @Field(() => String) 
      @prop({required: true})
      description: string;
    
      @Field(() => User) 
      @prop({ ref: () => User})
      public author: Ref<User>
    
      @Field(() => Float, {nullable: true}) 
      @prop()
      lat?: number
    
      @Field(() => Float, {nullable: true}) 
      @prop()
      lng?: number
    };
    
    export const Fridges = getModelForClass(Fridge);
    

    I don't fully understand how this would cause an unhanlded promise rejection. If anyone has any info it would be much appreciated because I was not able to find anything on my own.


  2.     @Resolver()
    export class FridgeResolver {
      @Mutation(() => Fridge)
      async createFridge (
        @Arg("inputs") inputs: FridgeInput,
        @Ctx() { req } : MyContext
      ): Promise<Fridge | undefined> {
          const author = await Users.findOne({_id: req.session.userId}); //You are using async function so you might have to use await here.
          const {name, address, description, coordinates} = inputs;
      
          const fridge = new Fridges({
            name,
            address,
            description,
            author,
            coordinates: coordinates ? coordinates : undefined
          })
      
          try {
            await fridge.save()
          } catch (error) {
            console.log(error)
            return undefined
          } 
        
          return fridge
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search