Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Glassmyer2014-09-05 21:10:18 +0000
committerDani Megert2014-10-03 08:03:55 +0000
commit12a546175da71df1409f01c4e586391f3bff852d (patch)
treed8797a53ddf94d7d44176285492a913398c5bad3 /org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist
parent22b991e05e1d86e9fce2ae9c840f0964998296c8 (diff)
downloadeclipse.platform.text-12a546175da71df1409f01c4e586391f3bff852d.tar.gz
eclipse.platform.text-12a546175da71df1409f01c4e586391f3bff852d.tar.xz
eclipse.platform.text-12a546175da71df1409f01c4e586391f3bff852d.zip
Bug 434901 - catch Content Assist exceptions to protect navigation keys
Change-Id: I610382ad733198b931ca66bb0b25199eee956d3f Signed-off-by: John Glassmyer <jogl@google.com>
Diffstat (limited to 'org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist')
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistant.java107
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/JFaceTextMessages.properties3
2 files changed, 85 insertions, 25 deletions
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistant.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistant.java
index 5da648b484e..800bf93cdb4 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistant.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistant.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,6 +10,7 @@
* Guy Gurfinkel, guy.g@zend.com - [content assist][api] provide better access to ContentAssistant - https://bugs.eclipse.org/bugs/show_bug.cgi?id=169954
* Anton Leherbauer (Wind River Systems) - [content assist][api] ContentAssistEvent should contain information about auto activation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=193728
* Marcel Bruch, bruch@cs.tu-darmstadt.de - [content assist] Allow to re-sort proposals - https://bugs.eclipse.org/bugs/show_bug.cgi?id=350991
+ * John Glassmyer, jogl@google.com - catch Content Assist exceptions to protect navigation keys - http://bugs.eclipse.org/434901
*******************************************************************************/
package org.eclipse.jface.text.contentassist;
@@ -48,7 +49,12 @@ import org.eclipse.swt.widgets.Widget;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.core.runtime.Status;
import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.contentassist.IContentAssistSubjectControl;
@@ -831,6 +837,31 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
}
}
+ /**
+ * A subclass of ISafeRunnable which, in case of exception, logs a specified error message to the jface.text log and
+ * sets fLastErrorMessage to this message.
+ */
+ private abstract class ExceptionLoggingSafeRunnable implements ISafeRunnable {
+ private static final String PLUGIN_ID= "org.eclipse.jface.text"; //$NON-NLS-1$
+
+ private final String messageKey;
+
+ /**
+ * @param messageKey key passed to JFaceTextMessages to lookup the text of the error message
+ */
+ ExceptionLoggingSafeRunnable(String messageKey) {
+ this.messageKey = messageKey;
+ }
+
+ public void handleException(Throwable exception) {
+ String message = JFaceTextMessages.getString(messageKey);
+
+ IStatus status = new Status(IStatus.ERROR, PLUGIN_ID, message, exception);
+ Platform.getLog(Platform.getBundle(PLUGIN_ID)).log(status);
+
+ fLastErrorMessage = message;
+ }
+ }
/**
* Dialog store constant for the x-size of the completion proposal pop-up
@@ -875,6 +906,8 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
public static final int WIDGET_PRIORITY= 20;
private static final int DEFAULT_AUTO_ACTIVATION_DELAY= 500;
+ private static final String COMPLETION_ERROR_MESSAGE_KEY= "ContentAssistant.error_computing_completion"; //$NON-NLS-1$
+ private static final String CONTEXT_ERROR_MESSAGE_KEY= "ContentAssistant.error_computing_context"; //$NON-NLS-1$
private IInformationControlCreator fInformationControlCreator;
private int fAutoActivationDelay= DEFAULT_AUTO_ACTIVATION_DELAY;
@@ -1828,18 +1861,25 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
* @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int)
* @since 3.0
*/
- ICompletionProposal[] computeCompletionProposals(IContentAssistSubjectControl contentAssistSubjectControl, int offset) {
+ ICompletionProposal[] computeCompletionProposals(
+ final IContentAssistSubjectControl contentAssistSubjectControl, final int offset) {
fLastErrorMessage= null;
- ICompletionProposal[] result= null;
+ final ICompletionProposal[][] result= { null };
- IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset);
+ final IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset);
if (p instanceof ISubjectControlContentAssistProcessor) {
- result= ((ISubjectControlContentAssistProcessor) p).computeCompletionProposals(contentAssistSubjectControl, offset);
- fLastErrorMessage= p.getErrorMessage();
+ // Ensure that the assist session ends cleanly even if the processor throws an exception.
+ SafeRunner.run(new ExceptionLoggingSafeRunnable(COMPLETION_ERROR_MESSAGE_KEY) {
+ public void run() throws Exception {
+ result[0]= ((ISubjectControlContentAssistProcessor) p)
+ .computeCompletionProposals(contentAssistSubjectControl, offset);
+ fLastErrorMessage= p.getErrorMessage();
+ }
+ });
}
- return result;
+ return result[0];
}
/**
@@ -1851,18 +1891,23 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
* @return an array of completion proposals or <code>null</code> if no proposals are possible
* @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int)
*/
- ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+ ICompletionProposal[] computeCompletionProposals(final ITextViewer viewer, final int offset) {
fLastErrorMessage= null;
- ICompletionProposal[] result= null;
+ final ICompletionProposal[][] result= { null };
- IContentAssistProcessor p= getProcessor(viewer, offset);
+ final IContentAssistProcessor p= getProcessor(viewer, offset);
if (p != null) {
- result= p.computeCompletionProposals(viewer, offset);
- fLastErrorMessage= p.getErrorMessage();
+ // Ensure that the assist session ends cleanly even if the processor throws an exception.
+ SafeRunner.run(new ExceptionLoggingSafeRunnable(COMPLETION_ERROR_MESSAGE_KEY) {
+ public void run() throws Exception {
+ result[0]= p.computeCompletionProposals(viewer, offset);
+ fLastErrorMessage= p.getErrorMessage();
+ }
+ });
}
- return result;
+ return result[0];
}
/**
@@ -1875,18 +1920,23 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
* @return an array of context information objects
* @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
*/
- IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
+ IContextInformation[] computeContextInformation(final ITextViewer viewer, final int offset) {
fLastErrorMessage= null;
- IContextInformation[] result= null;
+ final IContextInformation[][] result= { null };
- IContentAssistProcessor p= getProcessor(viewer, offset);
+ final IContentAssistProcessor p= getProcessor(viewer, offset);
if (p != null) {
- result= p.computeContextInformation(viewer, offset);
- fLastErrorMessage= p.getErrorMessage();
+ // Ensure that the assist session ends cleanly even if the processor throws an exception.
+ SafeRunner.run(new ExceptionLoggingSafeRunnable(CONTEXT_ERROR_MESSAGE_KEY) {
+ public void run() throws Exception {
+ result[0]= p.computeContextInformation(viewer, offset);
+ fLastErrorMessage= p.getErrorMessage();
+ }
+ });
}
- return result;
+ return result[0];
}
/**
@@ -1900,18 +1950,25 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
* @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
* @since 3.0
*/
- IContextInformation[] computeContextInformation(IContentAssistSubjectControl contentAssistSubjectControl, int offset) {
+ IContextInformation[] computeContextInformation(
+ final IContentAssistSubjectControl contentAssistSubjectControl, final int offset) {
fLastErrorMessage= null;
- IContextInformation[] result= null;
+ final IContextInformation[][] result= { null };
- IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset);
+ final IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset);
if (p instanceof ISubjectControlContentAssistProcessor) {
- result= ((ISubjectControlContentAssistProcessor) p).computeContextInformation(contentAssistSubjectControl, offset);
- fLastErrorMessage= p.getErrorMessage();
+ // Ensure that the assist session ends cleanly even if the processor throws an exception.
+ SafeRunner.run(new ExceptionLoggingSafeRunnable(CONTEXT_ERROR_MESSAGE_KEY) {
+ public void run() throws Exception {
+ result[0]= ((ISubjectControlContentAssistProcessor) p)
+ .computeContextInformation(contentAssistSubjectControl, offset);
+ fLastErrorMessage= p.getErrorMessage();
+ }
+ });
}
- return result;
+ return result[0];
}
/**
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/JFaceTextMessages.properties b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/JFaceTextMessages.properties
index 54b3cb98a2c..84f874a5a63 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/JFaceTextMessages.properties
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/JFaceTextMessages.properties
@@ -8,6 +8,7 @@
# Contributors:
# IBM Corporation - initial API and implementation
# Terry Parker, tparker@google.com - Protect against poorly behaved completion proposers - http://bugs.eclipse.org/429925
+# John Glassmyer, jogl@google.com - catch Content Assist exceptions to protect navigation keys - https://bugs.eclipse.org/434901
###############################################################################
@@ -15,6 +16,8 @@ InfoPopup.info_delay_timer_name=Additional info timer
AdditionalInfoController.job_name=Computing additional info
ContentAssistant.assist_delay_timer_name=AutoAssist Delay
+ContentAssistant.error_computing_completion=Error computing completion proposals.
+ContentAssistant.error_computing_context=Error computing context information.
CompletionProposalPopup.no_proposals=no proposals
CompletionProposalPopup.error_retrieving_proposal=Error retrieving proposal text
CompletionProposalPopup.unexpected_error=Unexpected error while retrieving text for a content assistance proposal.

Back to the top