Repository: gatsbyjs/gatsby
File: packages/gatsby-transformer-sharp/src/customize-schema.js (JavaScript)

Code before:
        },
      }),
      args: {},
      async resolve(image, fieldArgs, context) {
        const details = getNodeAndSavePathDependency(image.parent, context.path)
        const dimensions = imageSize.sync(
          toArray(fs.readFileSync(details.absolutePath))
        )
        const imageName = `${details.name}-${image.internal.contentDigest}${details.ext}`
        const publicPath = path.join(
          process.cwd(),
          `public`,
          `static`,
          imageName
        )

        if (!fs.existsSync(publicPath) && !inProgressCopy.has(publicPath)) {
          // keep track of in progress copy, we should rely on `existsSync` but
          // a race condition exists between the exists check and the copy
          inProgressCopy.add(publicPath)
          fs.copy(details.absolutePath, publicPath, err => {
            // this is no longer in progress
            inProgressCopy.delete(publicPath)
            if (err) {
              // Capture error within new Reporter API
              if (reporter.setErrorMap) {
                reporter.panic({
                  id: `TBD`,
                  error: err
                },
                err)
              } else {  // "old" error handling (except, now, we use `reporter.panic` instead of `console.error`)
                reporter.panic(`error copying file from ${details.absolutePath} to ${publicPath}`)
              }
            }
          })
        }

        return {
          width: dimensions.width,
          height: dimensions.height,
          src: `${pathPrefix}/static/${imageName}`,
        }
      },
    },
    resize: {
      type: new GraphQLObjectType({
        name: `ImageSharpResize`,
        fields: {
          src: { type: GraphQLString },
          tracedSVG: {

Review comment (suggestion):
Same suggestion here. We can call it in a backwards compatible way by putting the message in `context.sourceMessage`, and then we can actually pass the `err` object as the second argument to `panic`

Code after:
        },
      }),
      args: {},
      async resolve(image, fieldArgs, context) {
        const details = getNodeAndSavePathDependency(image.parent, context.path)
        const dimensions = imageSize.sync(
          toArray(fs.readFileSync(details.absolutePath))
        )
        const imageName = `${details.name}-${image.internal.contentDigest}${details.ext}`
        const publicPath = path.join(
          process.cwd(),
          `public`,
          `static`,
          imageName
        )

        if (!fs.existsSync(publicPath) && !inProgressCopy.has(publicPath)) {
          // keep track of in progress copy, we should rely on `existsSync` but
          // a race condition exists between the exists check and the copy
          inProgressCopy.add(publicPath)
          fs.copy(details.absolutePath, publicPath, err => {
            // this is no longer in progress
            inProgressCopy.delete(publicPath)
            if (err) {
              reporter.panic(
                {
                  id: prefixId(CODES.MissingResource),
                  context: {
                    sourceMessage: `error copying file from ${details.absolutePath} to ${publicPath}`,
                  },
                },
                err
              )
            }
          })
        }

        return {
          width: dimensions.width,
          height: dimensions.height,
          src: `${pathPrefix}/static/${imageName}`,
        }
      },
    },
    resize: {
      type: new GraphQLObjectType({
        name: `ImageSharpResize`,
        fields: {
          src: { type: GraphQLString },
          tracedSVG: {
            type: GraphQLString,