 					if @$scope.state.loading
 						@$scope.state.load_progress = 70
 
+				# we have passed authentication so we can now join the project
 				setTimeout(() =>
 					@joinProject()
 				, 100)
+
+			@ide.socket.on 'connectionRejected', (err) =>
+				sl_console.log "[socket.io connectionRejected] session not valid or other connection error"
+				# we have failed authentication, usually due to an invalid session cookie
+				return @reportConnectionError(err)
+
+			# Alternatively the attempt to connect can fail completely, so
+			# we never get into the "connect" state.
 
 			@ide.socket.on "connect_failed", () =>
 				@connected = false
 				$scope.$apply () =>
 					@$scope.state.error = "Unable to connect, please view the <u><a href='http://sharelatex.tenderapp.com/help/kb/latex-editor/editor-connection-problems'>connection problems guide</a></u> to fix the issue."
 
-
+			# We can get a "disconnect" event at any point after the
+			# "connect" event.
 
 			@ide.socket.on 'disconnect', () =>
 				sl_console.log "[socket.io disconnect] Disconnected"


				if !$scope.connection.forced_disconnect and !@userIsInactive and !@gracefullyReconnecting
					@startAutoReconnectCountdown()

			@ide.socket.on 'forceDisconnect', (message) =>
				@$scope.$apply () =>

				setTimeout () ->
					location.reload()
				, 10 * 1000

			@ide.socket.on "reconnectGracefully", () =>
				sl_console.log "Reconnect gracefully"
				@reconnectGracefully()

		# Error reporting, which can reload the page if appropriate

		reportConnectionError: (err) ->
			sl_console.log "[socket.io] reporting connection error"
			if err?.message == "not authorized" or err?.message == "invalid session"
				window.location = "/login?redir=#{encodeURI(window.location.pathname)}"
			else
				@ide.socket.disconnect()
				@ide.showGenericMessageModal("Something went wrong connecting", """
					Something went wrong connecting to your project. Please refresh is this continues to happen.
				""")

		joinProject: () ->
			sl_console.log "[joinProject] joining..."
			# Note: if the "joinProject" message doesn't reach the server
			# (e.g. if we are in a disconnected state at this point) the
			# callback will never be executed
			@ide.socket.emit 'joinProject', {
				project_id: @ide.project_id
			}, (err, project, permissionsLevel, protocolVersion) =>
				if err?
					return @reportConnectionError(err)

				if @$scope.protocolVersion? and @$scope.protocolVersion != protocolVersion
					location.reload(true)
