<commit_before>var path = require('path')
var menubar = require('menubar')
var DDPClient = require('ddp')
var EJSON = require('ddp-ejson')
var moment = require('moment')

var mb = menubar({
  icon: path.join(__dirname, 'noun_184605.png'),
  height: 50
})

mb.on('ready', () => {
  console.log('Did you dry these in a rain forest?')

  mb.tray.setPressedImage(path.join(__dirname, 'noun_184605_pressed.png'))

  mb.on('after-create-window', () => {
    mb.window.webContents.on('did-finish-load', send)
  })

  mb.on('show', () => {
    getDdpClient()
    send()
  })

  getDdpClient()
})

var getDdpClient = (() => {
  var ddpClient
  var heartbeatTimeout

  return () => {
    if (ddpClient) return ddpClient

    ddpClient = new DDPClient({url: 'wss://makelunch.meteor.com/websocket', useSockJs: false})

    // Close the connection if heartbeat not recieved
    ddpClient.on('message', data => {
      data = EJSON.parse(data)
      if (data.msg !== 'ping') return

      clearTimeout(heartbeatTimeout)

      heartbeatTimeout = setTimeout(() => {
        if (!ddpClient) return
        console.log('DDP heatbeat timeout')
        ddpClient.close()
        ddpClient = null
      }, 60000)
    })

    ddpClient.on('socket-error', err => {
      console.error('DDP socket error', err)
      clearTimeout(heartbeatTimeout)
      ddpClient.close()
      ddpClient = null
    })

    ddpClient.connect(onConnect)

    return ddpClient
  }

  function onConnect (err, wasReconnect) {
    if (err) {
      console.error('DDP connection error', err)
      clearTimeout(heartbeatTimeout)
      ddpClient.close()
      ddpClient = null
      return
    }

    console.log(`DDP ${wasReconnect ? 're' : ''}connected`)

    ddpClient.subscribe('eaters', [], err => {
      if (err) return console.error('Failed to subscribe to eaters', err)
      send()
    })
  }
})()<commit_msg>Add guard around client close on socket error because it may already be null if error while connecting<commit_after>var path = require('path')
var menubar = require('menubar')
var DDPClient = require('ddp')
var EJSON = require('ddp-ejson')
var moment = require('moment')

var mb = menubar({
  icon: path.join(__dirname, 'noun_184605.png'),
  height: 50
})

mb.on('ready', () => {
  console.log('Did you dry these in a rain forest?')

  mb.tray.setPressedImage(path.join(__dirname, 'noun_184605_pressed.png'))

  mb.on('after-create-window', () => {
    mb.window.webContents.on('did-finish-load', send)
  })

  mb.on('show', () => {
    getDdpClient()
    send()
  })

  getDdpClient()
})

var getDdpClient = (() => {
  var ddpClient
  var heartbeatTimeout

  return () => {
    if (ddpClient) return ddpClient

    ddpClient = new DDPClient({url: 'wss://makelunch.meteor.com/websocket', useSockJs: false})

    // Close the connection if heartbeat not recieved
    ddpClient.on('message', data => {
      data = EJSON.parse(data)
      if (data.msg !== 'ping') return

      clearTimeout(heartbeatTimeout)

      heartbeatTimeout = setTimeout(() => {
        console.log('DDP heatbeat timeout')
        if (!ddpClient) return
        ddpClient.close()
        ddpClient = null
      }, 60000)
    })

    ddpClient.on('socket-error', err => {
      console.error('DDP socket error', err)
      clearTimeout(heartbeatTimeout)
      if (!ddpClient) return
      ddpClient.close()
      ddpClient = null
    })

    ddpClient.connect(onConnect)

    return ddpClient
  }

  function onConnect (err, wasReconnect) {
    if (err) {
      console.error('DDP connection error', err)
      clearTimeout(heartbeatTimeout)
      ddpClient.close()
      ddpClient = null
      return
    }

    console.log(`DDP ${wasReconnect ? 're' : ''}connected`)

    ddpClient.subscribe('eaters', [], err => {
      if (err) return console.error('Failed to subscribe to eaters', err)
      send()
    })
  }
})()
{'fraction_non_alphanumeric': 0.14673913043478262, 'fraction_numerical': 0.009834368530020704, 'mean_word_length': 3.0134994807892004, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2413839', 'n_tokens_mistral': 1331, 'n_tokens_neox': 1260, 'n_words': 280}