Error: Unable to determine event source based on event. (apollo-server-lambda)

I have this issue after updating to apollo-server-lambda@3^

“Error: Unable to determine event source based on event.”

This code used to work a while ago but since the version 3^ of apollo-server-lambda my code is breaking and gives me the error message above…

This is my netlify back-end function code: (graphql.js)

const {
  ApolloServerPluginLandingPageGraphQLPlayground,
  // ApolloServerPluginLandingPageDisabled,
} = require('apollo-server-core');
const faunadb = require('faunadb');

const q = faunadb.query;

const client = new faunadb.Client({ secret: process.env.GATSBY_FAUNADB });

const typeDefs = gql`
  type Query {
    todos: [Todo]!
  }
  type Todo {
    id: ID!
    text: String!
    done: Boolean!
  }
  type Mutation {
    addTodo(text: String!): Todo
    updateTodoDone(id: ID!): Todo
  }
`;

const resolvers = {
  Query: {
    todos: async (parents, args, { user }) => {
      if (!user) {
        return [];
      }
      const results = await client.query(
        q.Paginate(q.Match(q.Index('todos_by_user'), user)),
      );
      return results.data.map(([ref, text, done]) => ({
        id: ref.id,
        text,
        done,
      }));
    },
  },

  Mutation: {
    addTodo: async (_, { text }, { user }) => {
      if (!user) {
        throw new Error('voer ieks goeds in man');
      }
      const results = await client.query(
        q.Create(q.Collection('todos'), {
          data: { text, done: false, owner: user },
        }),
      );

      return {
        ...results.data,
        id: results.ref.id,
      };
    },

    updateTodoDone: async (_, { id }, { user }) => {
      if (!user) {
        throw new Error('voer ieks goeds in man ali boalowii');
      }
      const results = await client.query(
        q.Update(q.Ref(q.Collection('todos'), id), { data: { done: true } }),
      );
      return {
        ...results.data,
        id: results.ref.id,
      };
    },
  },
};

console.log('CLIENT grapqhl #mnfx', client);

// const apolloHandler = server.createHandler();

exports.handler = async (event, context) => {
  try {
    const server = new ApolloServer({
      typeDefs,
      resolvers,

      context: async () => {
        // console.log('ff checken event', event);
        console.log('ff checken context', context);

        if (context.clientContext.user) {
          return {
            event,
            context,
            user: context.clientContext.user.sub,
          };
        }
        return {};
      },

      // playground
      playground: [ApolloServerPluginLandingPageGraphQLPlayground()],
      introspection: true,
    });

    const apolloHandler = server.createHandler({
      expressGetMiddlewareOptions: {
        cors: {
          origin: '*',
          credentials: true,
        },
      },
    });

    console.log('before event ish:', event);
    console.log('before context ish:', context);

    return await apolloHandler(event, context);
  } catch (err) {
    return console.error('Failed ISH!', err);
  }
};

This is the wrapper file: (gatsby-browser.js)

/* eslint-disable prettier/prettier */
/* eslint-disable react/jsx-props-no-spreading */
const React = require('react');

const {
  ApolloProvider,
  ApolloClient,
  HttpLink,
  InMemoryCache,
} = require('@apollo/client');

require('bootstrap/dist/css/bootstrap.min.css');

const netlifyIdentity = require('netlify-identity-widget');

const { setContext } = require('@apollo/client/link/context');

// const fetch = require('isomorphic-fetch');
const fetch = require('cross-fetch');
// const fetch = require('node-fetch');

const { IdentityProvider } = require('./src/context/identity-context');

const Layout = require('./src/components/layout').default;

const authLink = setContext((_, { headers }) => {
  const user = netlifyIdentity.currentUser();
  const token = user.token.access_token;

  console.log('HEADERS @ gatsby-browser #mnfx:', headers);
  console.log('USER @ gatsby-browser #mnfx:', user);
  console.log('TOKEN @ gatsby-browser  #mnfx:', token);

  return {
    headers: {
      ...headers,
      Authorization: token ? `Bearer ${token}` : '',
    },
  };
});

const httpLink = new HttpLink({
  fetch,
  uri: 'https://afrodiasphere.netlify.app/.netlify/functions/graphql',
});


const client = new ApolloClient({
  ssrMode: true,
  cache: new InMemoryCache(),
  link: authLink.concat(httpLink),
});

const wrapPageElement = ({ element, props }) => (
  <Layout {...props}>{element}</Layout>
);

exports.wrapPageElement = wrapPageElement;

const wrapRootElement = ({ element }) => (
  <ApolloProvider client={client}>
    <IdentityProvider>{element}</IdentityProvider>
  </ApolloProvider>
);

exports.wrapRootElement = wrapRootElement;

// export const onPreRouteUpdate = ({ location, prevLocation }) => {
//   console.log('new pathname', location.pathname);
//   console.log('old pathname', prevLocation ? prevLocation.pathname : null);
// };

And to make it complete, also the front-end page: (dashboard.tsx)

import React, { useContext, useRef } from 'react';

import { gql, useMutation, useQuery } from '@apollo/client';
import { Button, Form, ListGroup, InputGroup } from 'react-bootstrap';

import IdentityContext from '../context/identity-context';

// interface Props {}

const ADD_TODO = gql`
  mutation AddTodo($text: String!) {
    addTodo(text: $text) {
      id
    }
  }
`;

const UPDATE_TODO_DONE = gql`
  mutation UpdateTodoDone($id: ID!) {
    updateTodoDone(id: $id) {
      text
      done
    }
  }
`;

const GET_TODOS = gql`
  query GetTodos {
    todos {
      id
      text
      done
    }
  }
`;

const Dashboard = () => {
  const { user, identity: netlifyIdentity } = useContext(IdentityContext);

  const inputRef = useRef();

  const [addTodo] = useMutation(ADD_TODO);
  const [updateTodoDone] = useMutation(UPDATE_TODO_DONE);
  const { loading, error, data, refetch } = useQuery(GET_TODOS);

  console.log(data);
  // console.log('displatch! :', dispatch, 'data! :', data);

  return (
    <div>
      <span>Hallo {user && user.user_metadata.full_name}, welkom!</span>

      {user && (
        <Button
          variant="outline-danger"
          type="button"
          className="px-4 mx-4"
          onClick={() => {
            netlifyIdentity.logout();
          }}
        >
          Log out {user.user_metadata.full_name}
        </Button>
      )}

      <div className="container my-5">
        <Form
          onSubmit={async (e) => {
            e.preventDefault();
            await addTodo({ variables: { text: inputRef.current.value } });
            inputRef.current.value = '';
            await refetch();
          }}
        >
          <Form.Group className="d-flex justify-content-between">
            <Form.Label htmlFor="add-die-todo">Add een todo </Form.Label>
            <Form.Control type="text" placeholder="Enter text" ref={inputRef} />
            <Button type="submit" className="mb-2">
              Submit
            </Button>
          </Form.Group>

          <div className="container mt-5 ">
            {loading ? <div>loading...</div> : null}
            {error ? <div>{error.message}</div> : null}
            {!loading && !error && (
              <ListGroup as="ul">
                {data.todos.map((todo) => (
                  <ListGroup.Item
                    eventKey={todo.id}
                    key={todo.id}
                    as="li"
                    className="d-flex justify-content-evenly"
                    onClick={async () => {
                      await updateTodoDone({ variables: { id: todo.id } });
                      await refetch();
                    }}
                  >
                    <InputGroup.Checkbox
                      aria-label="Checkbox for following text input"
                      checked={todo.done}
                    />
                    <span>{todo.text}</span>
                  </ListGroup.Item>
                ))}
                {console.log('DATA van dashboard #mnfx:', data)}
              </ListGroup>
            )}
          </div>
        </Form>
      </div>
    </div>
  );
};

export default Dashboard;

I think this must do it… Help is greatly wanted. Thanks in advance!

Hey @mikeyfe6,

I think this question is more suitable for apollo-sever-lambda as, just like you say this is caused by upgrading the version. So, there could be some breaking changes, but having no experience we the library, we can’t comment on that.