 					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"

				setTimeout () ->
					location.reload()
				, 10 * 1000
			
			@ide.socket.on "reconnectGracefully", () =>
				sl_console.log "Reconnect gracefully"
				@reconnectGracefully()

		joinProject: () ->
			sl_console.log "[joinProject] joining..."
			@ide.socket.emit 'joinProject', {
				project_id: @ide.project_id
			}, (err, project, permissionsLevel, protocolVersion) =>
				if err?
					if err.message == "not authorized"
						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.
						""")
					return

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

			@reconnectGracefullyStarted = null
			# Clear cookie so we don't go to the same backend server
			$.cookie("SERVERID", "", { expires: -1, path: "/" })
			@reconnectImmediately()
