diff options
author | eutarass | 2008-06-25 07:05:22 +0000 |
---|---|---|
committer | eutarass | 2008-06-25 07:05:22 +0000 |
commit | 22448ad8dad9f5ef72c65700bfaf86913effb051 (patch) | |
tree | 3fca405069460163eaa4c4cb7f7c1a237dc42769 | |
parent | b975e7bbc93133f35a5bc31747e2c7e30f5c2d5d (diff) | |
download | org.eclipse.tcf-22448ad8dad9f5ef72c65700bfaf86913effb051.tar.gz org.eclipse.tcf-22448ad8dad9f5ef72c65700bfaf86913effb051.tar.xz org.eclipse.tcf-22448ad8dad9f5ef72c65700bfaf86913effb051.zip |
Bug 232410: [tcf][api] TCF needs standard way to define agent error codes
21 files changed, 485 insertions, 291 deletions
diff --git a/docs/TCF Service - File System.html b/docs/TCF Service - File System.html index dd10042bb..9ccef52aa 100644 --- a/docs/TCF Service - File System.html +++ b/docs/TCF Service - File System.html @@ -160,51 +160,22 @@ Tools and targets can define additional attributes. Predefined attributes are:</ <p>The service uses standard format for error reports, see <a href='TCF Services.html#ErrorFormat'>Error Report Format</a>.</p> -<p>Currently, the following values are defined for error code (other values may be +<p>Currently, the following values are defined for service specific error codes (other values may be defined by future versions of this protocol):</p> <dl> - <dt><code>STATUS_OK = 0</code> - <dd>Indicates successful completion of the operation. - - <dt><code>STATUS_EOF = 1</code> + <dt><code>EOF = 0x10001</code> <dd>Indicates end-of-file condition; for 'read' it means that no more data is available in the file, and for 'readdir' it indicates that no more files are contained in the directory. - <dt><code>STATUS_NO_SUCH_FILE = 2</code> + <dt><code>NO_SUCH_FILE = 0x10002</code> <dd>This code is returned when a reference is made to a file which should exist but doesn't. - <dt><code>STATUS_PERMISSION_DENIED = 3</code> + <dt><code>PERMISSION_DENIED = 0x10003</code> <dd>is returned when the authenticated user does not have sufficient permissions to perform the operation. - - <dt><code>STATUS_FAILURE = 4</code> - <dd>is a generic catch-all error message; it should be returned if an - error occurs for which there is no more specific error code. - - <dt><code>STATUS_BAD_MESSAGE = 5</code> - <dd>may be returned if a badly formatted packet or protocol - incompatibility is detected. - - <dt><code>STATUS_NO_CONNECTION = 6</code> - <dd>is a pseudo-error which indicates that the client has no - connection to the server (it can only be generated locally by the - client, and MUST NOT be returned by servers). - - <dt><code>STATUS_CONNECTION_LOST = 7</code> - <dd>is a pseudo-error which indicates that the connection to the - server has been lost (it can only be generated locally by the - client, and MUST NOT be returned by servers). - - <dt><code>STATUS_OP_UNSUPPORTED = 8</code> - <dd>indicates that an attempt was made to perform an operation which - is not supported for the server (it may be generated locally by - the client if e.g. the version number exchange indicates that a - required feature is not supported by the server, or it may be - returned by the server if the server does not implement an - operation). </dl> <h2><a name='Cmds'>Commands</a></h2> diff --git a/docs/TCF Service - Memory.html b/docs/TCF Service - Memory.html index 199a474eb..0e93e36b0 100644 --- a/docs/TCF Service - Memory.html +++ b/docs/TCF Service - Memory.html @@ -43,7 +43,7 @@ in addition to error report, describes data validity on per byte basis:</p> ⇒ <i><error address list></i> , <i><error address></i> <i><error address></i> - ⇒ { "addr" : <i><int: range starting address></i> , "size" : <i><int: range length in bytes></i> , "stat" : <i><int: status code></i> , "msg" : <i><error description></i> } + ⇒ { "addr" : <i><int: range starting address></i> , "size" : <i><int: range length in bytes></i> , "stat" : <i><int: status code></i> , "msg" : <i><object: error description></i> } </font></b></pre> <p>If there is no entry in error addresses array for a data byte, then status of such diff --git a/docs/TCF Services.html b/docs/TCF Services.html index f0a527563..8732cc374 100644 --- a/docs/TCF Services.html +++ b/docs/TCF Services.html @@ -67,29 +67,106 @@ using a simple variant of Backus-Naur Form. In particular:</p> <pre><b><font face="Courier New" size=2 color=#333399> <i><error report></i> - ⇒ <i><int: error code></i> • <i><error description></i> -</font></b></pre> - -<p>Error code zero means success. Error description provides a short, localizable, -human readable explanation of error.</p> - -<pre><b><font face="Courier New" size=2 color=#333399> -<i><error description></i> + ⇒ ⇒ null - ⇒ <i><string></i> - ⇒ { "format" : <i><string></i> , "params" : [ <i><params></i> ] } - -<i><params></i> - ⇒ <i><value></i> - ⇒ <i><params></i> , <i><value></i> + ⇒ <i><object: error description></i> </font></b></pre> -<p>For <b><i><font face="Courier New" size=2 color=#333399><string></font></i></b> -and <b><i><font face="Courier New" size=2 color=#333399><value></font></i></b> encoding see +<p>Empty or null error report means success. Error description provides error details, including +error code and a short, localizable, human readable explanation of the error.</p> + +<p>Error description properties are:</p> +<dl> + <dt><b><font face="Courier New" size=2 color=#333399>"Code" : <i><integer></i></font></b> + <dd>Error code. Can belong to one of predefined ranges: + <ul> + <li> 0x0-0xffff Standard TCF codes, includes a limited subset of POSIX errors, and OTHER error code, which + can be used together with "AltCode" + <li> 0x10000-0x1ffff Service specific codes + <li> 0x20000-0x2ffff Reserved codes - will never be used by the TCF standard + </ul> + + <dt><b><font face="Courier New" size=2 color=#333399>"Time" : <i><integer></i></font></b> + <dd> Error timestamp, in milliseconds since midnight, January 1, 1970 UTC + + <dt><b><font face="Courier New" size=2 color=#333399>"Service" : <i><string></i></font></b> + <dd> Name of the service that reported the error. Required when "Code" is service specific code. + + <dt><b><font face="Courier New" size=2 color=#333399>"Format" : <i><string></i></font></b> + <dd> Error description format supports separation between constant and variable parts + of error message ("Format" and "Params"). This is done to support localization. + Format string is expected to allow translation into foreign languages by means of string table lookup. + The format string syntax is defined in the Java language library + <b><font face="Courier New" size=2>java.text.MessageFormat</font></b>. + In order to simplify clients written in other languages, only a subset of the syntax is supported: + <ul> + <li> Supported format types: (none), number + <li> Supported format styles: + <ul> + <li> number: (none), "integer", "percent" + </ul> + </ul> + + <dt><b><font face="Courier New" size=2 color=#333399>"Params" : <i><array></i></font></b> + <dd> An array of values to be used together with "Format" to create the error message. + + <dt><b><font face="Courier New" size=2 color=#333399>"Severity" : <i><integer></i></font></b> + <dd> Predefined severity values: + <ul> + <li>0 - error (default) + <li>1 - warning + <li>2 - fatal + </ul> + + <dt><b><font face="Courier New" size=2 color=#333399>"AltCode" : <i><integer></i></font></b> + <dd> Alternative error code. This can be used to represent, + for example, OS, POSIX, or other vendor specific error codes + + <dt><b><font face="Courier New" size=2 color=#333399>"AltOrg" : <i><string></i></font></b> + <dd> ID of organization defining "AltCode", for example "Linux", "VxWorks", "Wind River", etc + + <dt><b><font face="Courier New" size=2 color=#333399>"CausedBy" : <i><object: error description></i></font></b> + <dd> A nested error description. Can be used to describe a root cause of this error. +</dl> + +<p>All fields except "Code" are optional.</p> + +<p>Standard error codes: +<pre><code> + OTHER = 1 + JSON_SYNTAX = 2 + PROTOCOL = 3 + BUFFER_OVERFLOW = 4 + CHANNEL_CLOSED = 5 + COMMAND_CANCELLED = 6 + UNKNOWN_PEER = 7 + BASE64 = 8 + EOF = 9 + ALREADY_STOPPED = 10 + ALREADY_EXITED = 11 + ALREADY_RUNNING = 12 + ALREADY_ATTACHED = 13 + IS_RUNNING = 14 + INV_DATA_SIZE = 15 + INV_CONTEXT = 16 + INV_ADDRESS = 17 + INV_EXPRESSION = 18 + INV_FORMAT = 19 + INV_NUMBER = 20 + INV_DWARF = 21 + SYM_NOT_FOUND = 22 + UNSUPPORTED = 23 +</code></pre> +</p> + +<p>Service specific error code definitions, if any, are part of service specfications. +Standard and service specific error codes can be extended over time. A +client that does not recognize a specific error code should treat it in the +same way as "OTHER".</p> + +<p>For encoding of <b><i><font face="Courier New" size=2 color=#333399><object></font></i></b>, +<b><i><font face="Courier New" size=2 color=#333399><string></font></i></b>, etc., see <a href='TCF Specification.html#JSON'>JSON - Preferred Marshaling</a>. -Error description format supports separation between constant and variable parts -of the message ("format" and "params"). This is done to support localization. See -Java class <b><font face="Courier New" size=2>java.text.MessageFormat</font></b> for details.</p> <h2><a name='Services'>Services</h2> <ul> diff --git a/examples/org.eclipse.tm.tcf.examples.daytime/src/org/eclipse/tm/internal/tcf/examples/daytime/DaytimeServiceProxy.java b/examples/org.eclipse.tm.tcf.examples.daytime/src/org/eclipse/tm/internal/tcf/examples/daytime/DaytimeServiceProxy.java index 4270aee4d..cefa9b92e 100644 --- a/examples/org.eclipse.tm.tcf.examples.daytime/src/org/eclipse/tm/internal/tcf/examples/daytime/DaytimeServiceProxy.java +++ b/examples/org.eclipse.tm.tcf.examples.daytime/src/org/eclipse/tm/internal/tcf/examples/daytime/DaytimeServiceProxy.java @@ -45,9 +45,9 @@ public class DaytimeServiceProxy implements IDaytimeService { public void done(Exception error, Object[] args) { String str = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - str = (String)args[2]; + assert args.length == 2; + error = toError(args[0]); + str = (String)args[1]; } done.doneGetTimeOfDay(token, error, str); } diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFSelfTest.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFSelfTest.java index 7e7c36211..ea790e6a3 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFSelfTest.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFSelfTest.java @@ -407,6 +407,12 @@ class TCFSelfTest { assert context != null; IRunControl.RunControlContext ctx = map.get(context); if (ctx == null) exit(new Error("Invalid 'contextSuspended' event for " + context)); + if (process_ids.contains(ctx.getParentID())) { + ctx.resume(IRunControl.RM_RESUME, 1, new IRunControl.DoneCommand() { + public void doneCommand(IToken token, Exception error) { + } + }); + } } } diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationManager.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationManager.java index 4ec3fbded..d44e61ef6 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationManager.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationManager.java @@ -181,8 +181,13 @@ public class TCFAnnotationManager { TCFLaunch.addListener(launch_listener); displayExec(new Runnable() { public void run() { - for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows()) { - window_listener.windowOpened(window); + try { + for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows()) { + window_listener.windowOpened(window); + } + } + catch (NullPointerException x) { + // TODO: bug in Eclipse: NullPointerException is thrown by getWorkbenchWindows() } PlatformUI.getWorkbench().addWindowListener(window_listener); IWorkbenchWindow w = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/BreakpointsProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/BreakpointsProxy.java index 577681ca8..38f383b9d 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/BreakpointsProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/BreakpointsProxy.java @@ -37,8 +37,8 @@ public class BreakpointsProxy implements IBreakpoints { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneCommand(token, error); } @@ -50,8 +50,8 @@ public class BreakpointsProxy implements IBreakpoints { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneCommand(token, error); } @@ -63,8 +63,8 @@ public class BreakpointsProxy implements IBreakpoints { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneCommand(token, error); } @@ -76,8 +76,8 @@ public class BreakpointsProxy implements IBreakpoints { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneCommand(token, error); } @@ -89,8 +89,8 @@ public class BreakpointsProxy implements IBreakpoints { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneCommand(token, error); } @@ -102,8 +102,8 @@ public class BreakpointsProxy implements IBreakpoints { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneCommand(token, error); } @@ -116,9 +116,9 @@ public class BreakpointsProxy implements IBreakpoints { public void done(Exception error, Object[] args) { String[] arr = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - arr = toStringArray(args[2]); + assert args.length == 2; + error = toError(args[0]); + arr = toStringArray(args[1]); } done.doneGetIDs(token, error, arr); } @@ -132,9 +132,9 @@ public class BreakpointsProxy implements IBreakpoints { public void done(Exception error, Object[] args) { Map<String,Object> map = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - map = (Map<String,Object>)args[2]; + assert args.length == 2; + error = toError(args[0]); + map = (Map<String,Object>)args[1]; } done.doneGetProperties(token, error, map); } @@ -148,9 +148,9 @@ public class BreakpointsProxy implements IBreakpoints { public void done(Exception error, Object[] args) { Map<String,Object> map = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - map = (Map<String,Object>)args[2]; + assert args.length == 2; + error = toError(args[0]); + map = (Map<String,Object>)args[1]; } done.doneGetStatus(token, error, map); } @@ -164,9 +164,9 @@ public class BreakpointsProxy implements IBreakpoints { public void done(Exception error, Object[] args) { Map<String,Object> map = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - map = (Map<String,Object>)args[2]; + assert args.length == 2; + error = toError(args[0]); + map = (Map<String,Object>)args[1]; } done.doneGetCapabilities(token, error, map); } diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/DiagnosticsProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/DiagnosticsProxy.java index 5fbdcb854..7f6ca9183 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/DiagnosticsProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/DiagnosticsProxy.java @@ -94,9 +94,9 @@ public class DiagnosticsProxy implements IDiagnostics { public void done(Exception error, Object[] args) { String[] arr = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - arr = toStringArray((Collection<String>)args[2]); + assert args.length == 2; + error = toError(args[0]); + arr = toStringArray((Collection<String>)args[1]); } done.doneGetTestList(token, error, arr); } @@ -109,9 +109,9 @@ public class DiagnosticsProxy implements IDiagnostics { public void done(Exception error, Object[] args) { String str = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - str = (String)args[2]; + assert args.length == 2; + error = toError(args[0]); + str = (String)args[1]; } done.doneRunTest(token, error, str); } @@ -123,8 +123,8 @@ public class DiagnosticsProxy implements IDiagnostics { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneCancelTest(token, error); } @@ -137,9 +137,9 @@ public class DiagnosticsProxy implements IDiagnostics { public void done(Exception error, Object[] args) { ISymbol sym = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - sym = toSymbol(args[2]); + assert args.length == 2; + error = toError(args[0]); + sym = toSymbol(args[1]); } done.doneGetSymbol(token, error, sym); } diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/FileSystemProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/FileSystemProxy.java index fb23c22e8..9c86e17d4 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/FileSystemProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/FileSystemProxy.java @@ -66,16 +66,18 @@ public class FileSystemProxy implements IFileSystem { super(channel, FileSystemProxy.this, command, args); } - public Status toFSError(Object code, Object data) { - int error_code = ((Number)code).intValue(); - if (error_code == 0) return null; + @SuppressWarnings("unchecked") + public Status toFSError(Object data) { + if (data == null) return null; + Map<String,Object> map = (Map<String,Object>)data; + Number error_code = (Number)map.get(ERROR_CODE); String cmd = getCommandString(); - if (cmd.length() > 32) cmd = cmd.substring(0, 32) + "..."; - return new Status(error_code, + if (cmd.length() > 72) cmd = cmd.substring(0, 72) + "..."; + return new Status(error_code.intValue(), "TCF command exception:" + "\nCommand: " + cmd + "\nException: " + toErrorString(data) + - "\nError code: " + code); + "\nError code: " + error_code); } } @@ -95,8 +97,8 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 2; - s = toFSError(args[0], args[1]); + assert args.length == 1; + s = toFSError(args[0]); } done.doneClose(token, s); } @@ -112,8 +114,8 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 2; - s = toFSError(args[0], args[1]); + assert args.length == 1; + s = toFSError(args[0]); } done.doneSetStat(token, s); } @@ -131,8 +133,8 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 2; - s = toFSError(args[0], args[1]); + assert args.length == 1; + s = toFSError(args[0]); } done.doneSetStat(token, s); } @@ -148,11 +150,9 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 3; - s = toFSError(args[0], args[1]); - if (s == null) { - a = toFileAttrs(args[2]); - } + assert args.length == 2; + s = toFSError(args[0]); + if (s == null) a = toFileAttrs(args[1]); } done.doneStat(token, s, a); } @@ -170,11 +170,9 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 3; - s = toFSError(args[0], args[1]); - if (s == null) { - a = toFileAttrs(args[2]); - } + assert args.length == 2; + s = toFSError(args[0]); + if (s == null) a = toFileAttrs(args[1]); } done.doneStat(token, s, a); } @@ -190,11 +188,9 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 3; - s = toFSError(args[0], args[1]); - if (s == null) { - a = toFileAttrs(args[2]); - } + assert args.length == 2; + s = toFSError(args[0]); + if (s == null) a = toFileAttrs(args[1]); } done.doneStat(token, s, a); } @@ -210,8 +206,8 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 2; - s = toFSError(args[0], args[1]); + assert args.length == 1; + s = toFSError(args[0]); } done.doneMkDir(token, s); } @@ -228,11 +224,9 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 3; - s = toFSError(args[0], args[1]); - if (s == null) { - h = toFileHandle(args[2]); - } + assert args.length == 2; + s = toFSError(args[0]); + if (s == null) h = toFileHandle(args[1]); } done.doneOpen(token, s, h); } @@ -248,11 +242,9 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 3; - s = toFSError(args[0], args[1]); - if (s == null) { - h = toFileHandle(args[2]); - } + assert args.length == 2; + s = toFSError(args[0]); + if (s == null) h = toFileHandle(args[1]); } done.doneOpen(token, s, h); } @@ -272,12 +264,12 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 4; - s = toFSError(args[1], args[2]); + assert args.length == 3; + s = toFSError(args[1]); if (s == null) { String str = (String)args[0]; if (str != null) b = Base64.toByteArray(str.toCharArray()); - eof = ((Boolean)args[3]).booleanValue(); + eof = ((Boolean)args[2]).booleanValue(); } } done.doneRead(token, s, b, eof); @@ -297,11 +289,11 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 4; - s = toFSError(args[1], args[2]); + assert args.length == 3; + s = toFSError(args[1]); if (s == null) { b = toDirEntryArray(args[0]); - eof = ((Boolean)args[3]).booleanValue(); + eof = ((Boolean)args[2]).booleanValue(); } } done.doneReadDir(token, s, b, eof); @@ -318,11 +310,9 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 3; - s = toFSError(args[1], args[2]); - if (s == null) { - b = toDirEntryArray(args[0]); - } + assert args.length == 2; + s = toFSError(args[1]); + if (s == null) b = toDirEntryArray(args[0]); } done.doneRoots(token, s, b); } @@ -338,11 +328,9 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 3; - s = toFSError(args[0], args[1]); - if (s == null) { - p = (String)args[2]; - } + assert args.length == 2; + s = toFSError(args[0]); + if (s == null) p = (String)args[1]; } done.doneReadLink(token, s, p); } @@ -358,11 +346,9 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 3; - s = toFSError(args[0], args[1]); - if (s == null) { - p = (String)args[2]; - } + assert args.length == 2; + s = toFSError(args[0]); + if (s == null) p = (String)args[1]; } done.doneRealPath(token, s, p); } @@ -377,8 +363,8 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 2; - s = toFSError(args[0], args[1]); + assert args.length == 1; + s = toFSError(args[0]); } done.doneRemove(token, s); } @@ -393,8 +379,8 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 2; - s = toFSError(args[0], args[1]); + assert args.length == 1; + s = toFSError(args[0]); } done.doneRename(token, s); } @@ -409,8 +395,8 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 2; - s = toFSError(args[0], args[1]); + assert args.length == 1; + s = toFSError(args[0]); } done.doneRemove(token, s); } @@ -425,8 +411,8 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 2; - s = toFSError(args[0], args[1]); + assert args.length == 1; + s = toFSError(args[0]); } done.doneSymLink(token, s); } @@ -445,8 +431,8 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 2; - s = toFSError(args[0], args[1]); + assert args.length == 1; + s = toFSError(args[0]); } done.doneWrite(token, s); } @@ -464,8 +450,8 @@ public class FileSystemProxy implements IFileSystem { s = new Status(error); } else { - assert args.length == 2; - s = toFSError(args[0], args[1]); + assert args.length == 1; + s = toFSError(args[0]); } done.doneCopy(token, s); } diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/LineNumbersProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/LineNumbersProxy.java index af3194fd4..3263e2dbe 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/LineNumbersProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/LineNumbersProxy.java @@ -29,9 +29,9 @@ public class LineNumbersProxy implements ILineNumbers { public void done(Exception error, Object[] args) { CodeArea[] arr = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - arr = toTextAreaArray(args[2]); + assert args.length == 2; + error = toError(args[0]); + arr = toTextAreaArray(args[1]); } done.doneMapToSource(token, error, arr); } diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/LocatorProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/LocatorProxy.java index c2304c2c9..cc09581e3 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/LocatorProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/LocatorProxy.java @@ -134,8 +134,8 @@ public class LocatorProxy implements ILocator { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneRedirect(token, error); } diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/MemoryProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/MemoryProxy.java index a2ed0c0e7..b51f5677a 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/MemoryProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/MemoryProxy.java @@ -168,8 +168,8 @@ public class MemoryProxy implements IMemory { e = new MemoryError(error.getMessage()); } else { - assert args.length == 3; - e = toMemoryError(addr, args[0], args[1], args[2]); + assert args.length == 2; + e = toMemoryError(addr, args[0], args[1]); } done.doneMemory(token, e); } @@ -188,10 +188,10 @@ public class MemoryProxy implements IMemory { e = new MemoryError(error.getMessage()); } else { - assert args.length == 4; + assert args.length == 3; String str = (String)args[0]; if (str != null) Base64.toByteArray(buf, offs, size, str.toCharArray()); - e = toMemoryError(addr, args[1], args[2], args[3]); + e = toMemoryError(addr, args[1], args[2]); } done.doneMemory(token, e); } @@ -209,8 +209,8 @@ public class MemoryProxy implements IMemory { e = new MemoryError(error.getMessage()); } else { - assert args.length == 3; - e = toMemoryError(addr, args[0], args[1], args[2]); + assert args.length == 2; + e = toMemoryError(addr, args[0], args[1]); } done.doneMemory(token, e); } @@ -274,11 +274,9 @@ public class MemoryProxy implements IMemory { public void done(Exception error, Object[] args) { MemContext ctx = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - if (args[2] != null) { - ctx = new MemContext((Map<String,Object>)args[2]); - } + assert args.length == 2; + error = toError(args[0]); + if (args[1] != null) ctx = new MemContext((Map<String,Object>)args[1]); } done.doneGetContext(token, error, ctx); } @@ -291,9 +289,9 @@ public class MemoryProxy implements IMemory { public void done(Exception error, Object[] args) { String[] arr = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - arr = toStringArray(args[2]); + assert args.length == 2; + error = toError(args[0]); + arr = toStringArray(args[1]); } done.doneGetChildren(token, error, arr); } @@ -310,9 +308,11 @@ public class MemoryProxy implements IMemory { super(channel, MemoryProxy.this, cmd, args); } - MemoryError toMemoryError(Number addr, Object code, Object data, Object ranges) { - int error_code = ((Number)code).intValue(); - if (error_code == 0) return null; + @SuppressWarnings("unchecked") + MemoryError toMemoryError(Number addr, Object data, Object ranges) { + if (data == null) return null; + Map<String,Object> map = (Map<String,Object>)data; + Integer code = (Integer)map.get(ERROR_CODE); String cmd = getCommandString(); if (cmd.length() > 72) cmd = cmd.substring(0, 72) + "..."; return new MemoryErrorReport( diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/ProcessesProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/ProcessesProxy.java index 829e41d83..e8b274c11 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/ProcessesProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/ProcessesProxy.java @@ -60,8 +60,8 @@ public class ProcessesProxy implements IProcesses { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneCommand(token, error); } @@ -74,8 +74,8 @@ public class ProcessesProxy implements IProcesses { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneCommand(token, error); } @@ -88,8 +88,8 @@ public class ProcessesProxy implements IProcesses { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneCommand(token, error); } @@ -102,8 +102,8 @@ public class ProcessesProxy implements IProcesses { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneCommand(token, error); } @@ -134,9 +134,9 @@ public class ProcessesProxy implements IProcesses { public void done(Exception error, Object[] args) { String[] ids = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - ids = toStringArray(args[2]); + assert args.length == 2; + error = toError(args[0]); + ids = toStringArray(args[1]); } done.doneGetChildren(token, error, ids); } @@ -151,11 +151,9 @@ public class ProcessesProxy implements IProcesses { public void done(Exception error, Object[] args) { ProcessContext ctx = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - if (args[2] != null) { - ctx = new ProcessContext((Map<String, Object>)args[2]); - } + assert args.length == 2; + error = toError(args[0]); + if (args[1] != null) ctx = new ProcessContext((Map<String, Object>)args[1]); } done.doneGetContext(token, error, ctx); } @@ -168,9 +166,9 @@ public class ProcessesProxy implements IProcesses { public void done(Exception error, Object[] args) { Map<String,String> env = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - env = toEnvMap(args[2]); + assert args.length == 2; + error = toError(args[0]); + env = toEnvMap(args[1]); } done.doneGetEnvironment(token, error, env); } @@ -188,11 +186,9 @@ public class ProcessesProxy implements IProcesses { public void done(Exception error, Object[] args) { ProcessContext ctx = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - if (args[2] != null) { - ctx = new ProcessContext((Map<String, Object>)args[2]); - } + assert args.length == 2; + error = toError(args[0]); + if (args[1] != null) ctx = new ProcessContext((Map<String, Object>)args[1]); } done.doneStart(token, error, ctx); } diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RegistersProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RegistersProxy.java index 127d58bc4..dc82c6f4c 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RegistersProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RegistersProxy.java @@ -138,9 +138,9 @@ public class RegistersProxy implements IRegisters { public void done(Exception error, Object[] args) { byte[] val = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - String str = (String)args[2]; + assert args.length == 2; + error = toError(args[0]); + String str = (String)args[1]; if (str != null) val = Base64.toByteArray(str.toCharArray()); } done.doneGet(token, error, val); @@ -154,8 +154,8 @@ public class RegistersProxy implements IRegisters { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneSet(token, error); } @@ -181,9 +181,9 @@ public class RegistersProxy implements IRegisters { public void done(Exception error, Object[] args) { String[] arr = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - arr = toStringArray(args[2]); + assert args.length == 2; + error = toError(args[0]); + arr = toStringArray(args[1]); } done.doneGetChildren(token, error, arr); } @@ -197,11 +197,9 @@ public class RegistersProxy implements IRegisters { public void done(Exception error, Object[] args) { Context ctx = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - if (args[2] != null) { - ctx = new Context((Map<String,Object>)args[2]); - } + assert args.length == 2; + error = toError(args[0]); + if (args[1] != null) ctx = new Context((Map<String,Object>)args[1]); } done.doneGetContext(token, error, ctx); } @@ -214,9 +212,9 @@ public class RegistersProxy implements IRegisters { public void done(Exception error, Object[] args) { byte[] val = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - String str = (String)args[2]; + assert args.length == 2; + error = toError(args[0]); + String str = (String)args[1]; if (str != null) val = Base64.toByteArray(str.toCharArray()); } done.doneGet(token, error, val); @@ -230,8 +228,8 @@ public class RegistersProxy implements IRegisters { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneSet(token, error); } diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RunControlProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RunControlProxy.java index 10bd33699..0925f93d8 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RunControlProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RunControlProxy.java @@ -96,12 +96,12 @@ public class RunControlProxy implements IRunControl { String reason = null; Map<String,Object> map = null; if (error == null) { - assert args.length == 6; - error = toError(args[0], args[1]); - susp = ((Boolean)args[2]).booleanValue(); - if (args[3] != null) pc = ((Number)args[3]).toString(); - reason = (String)args[4]; - map = (Map<String,Object>)args[5]; + assert args.length == 5; + error = toError(args[0]); + susp = ((Boolean)args[1]).booleanValue(); + if (args[2] != null) pc = ((Number)args[2]).toString(); + reason = (String)args[3]; + map = (Map<String,Object>)args[4]; } done.doneGetState(token, error, susp, pc, reason, map); } @@ -125,8 +125,8 @@ public class RunControlProxy implements IRunControl { @Override public void done(Exception error, Object[] args) { if (error == null) { - assert args.length == 2; - error = toError(args[0], args[1]); + assert args.length == 1; + error = toError(args[0]); } done.doneCommand(token, error); } @@ -217,11 +217,9 @@ public class RunControlProxy implements IRunControl { public void done(Exception error, Object[] args) { RunControlContext ctx = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - if (args[2] != null) { - ctx = new RunContext((Map<String, Object>)args[2]); - } + assert args.length == 2; + error = toError(args[0]); + if (args[1] != null) ctx = new RunContext((Map<String, Object>)args[1]); } done.doneGetContext(token, error, ctx); } @@ -234,9 +232,9 @@ public class RunControlProxy implements IRunControl { public void done(Exception error, Object[] args) { String[] arr = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - arr = toStringArray(args[2]); + assert args.length == 2; + error = toError(args[0]); + arr = toStringArray(args[1]); } done.doneGetChildren(token, error, arr); } diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/StackTraceProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/StackTraceProxy.java index 994bc6699..0907912dc 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/StackTraceProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/StackTraceProxy.java @@ -82,9 +82,9 @@ public class StackTraceProxy implements IStackTrace { public void done(Exception error, Object[] args) { String[] arr = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - arr = toStringArray(args[2]); + assert args.length == 2; + error = toError(args[0]); + arr = toStringArray(args[1]); } done.doneGetChildren(token, error, arr); } @@ -97,8 +97,8 @@ public class StackTraceProxy implements IStackTrace { public void done(Exception error, Object[] args) { StackTraceContext[] arr = null; if (error == null) { - assert args.length == 3; - error = toError(args[1], args[2]); + assert args.length == 2; + error = toError(args[1]); arr = toContextArray(args[0]); } done.doneGetContext(token, error, arr); diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/SysMonitorProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/SysMonitorProxy.java index 55fe26640..acaf5074f 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/SysMonitorProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/SysMonitorProxy.java @@ -139,9 +139,9 @@ public class SysMonitorProxy implements ISysMonitor { public void done(Exception error, Object[] args) { String[] arr = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - arr = toStringArray((Collection<String>)args[2]); + assert args.length == 2; + error = toError(args[0]); + arr = toStringArray((Collection<String>)args[1]); } done.doneGetChildren(token, error, arr); } @@ -155,11 +155,9 @@ public class SysMonitorProxy implements ISysMonitor { public void done(Exception error, Object[] args) { SysMonitorContext ctx = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - if (args[2] != null) { - ctx = new SysMonitorContext((Map<String, Object>)args[2]); - } + assert args.length == 2; + error = toError(args[0]); + if (args[1] != null) ctx = new SysMonitorContext((Map<String, Object>)args[1]); } done.doneGetContext(token, error, ctx); } @@ -173,9 +171,9 @@ public class SysMonitorProxy implements ISysMonitor { public void done(Exception error, Object[] args) { String[] arr = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - arr = toStringArray((Collection<String>)args[2]); + assert args.length == 2; + error = toError(args[0]); + arr = toStringArray((Collection<String>)args[1]); } done.doneGetCommandLine(token, error, arr); } @@ -189,9 +187,9 @@ public class SysMonitorProxy implements ISysMonitor { public void done(Exception error, Object[] args) { String[] arr = null; if (error == null) { - assert args.length == 3; - error = toError(args[0], args[1]); - arr = toStringArray((Collection<String>)args[2]); + assert args.length == 2; + error = toError(args[0]); + arr = toStringArray((Collection<String>)args[1]); } done.doneGetEnvironment(token, error, arr); } diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractChannel.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractChannel.java index b6c4af42d..750e26a8b 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractChannel.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractChannel.java @@ -226,10 +226,7 @@ public abstract class AbstractChannel implements IChannel { IOException x = new IOException("Connection reset by peer"); try { Object[] args = JSON.parseSequence(eos); - int error_code = ((Number)args[0]).intValue(); - if (error_code != 0) { - x = new IOException(Command.toErrorString(args[1])); - } + if (args[0] != null) x = new IOException(Command.toErrorString(args[0])); } catch (IOException e) { x = e; diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/Command.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/Command.java index 9a3d0600b..14ac70130 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/Command.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/Command.java @@ -12,11 +12,14 @@ package org.eclipse.tm.tcf.core; import java.io.IOException; import java.text.MessageFormat; +import java.text.SimpleDateFormat; import java.util.Collection; +import java.util.Date; import java.util.Map; import org.eclipse.tm.internal.tcf.core.Token; import org.eclipse.tm.tcf.protocol.IChannel; +import org.eclipse.tm.tcf.protocol.IErrorReport; import org.eclipse.tm.tcf.protocol.IService; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.protocol.JSON; @@ -26,8 +29,11 @@ import org.eclipse.tm.tcf.protocol.Protocol; /** * This is utility class that helps to implement sending a command and receiving * command result over TCF communication channel. The class uses JSON to encode - * command arguments and to decode result data. Clients are expected to subclass - * <code>Command</code> and override <code>done</code> method. + * command arguments and to decode result data. + * + * The class also provides support for TCF standard error report encoding. + * + * Clients are expected to subclass <code>Command</code> and override <code>done</code> method. * * Note: most clients don't need to handle protocol commands directly and * can use service APIs instead. Service API does all command encoding/decoding @@ -41,16 +47,16 @@ import org.eclipse.tm.tcf.protocol.Protocol; * public void done(Exception error, Object[] args) { * Context ctx = null; * if (error == null) { - * assert args.length == 3; - * error = JSON.toError(args[0], args[1]); - * if (args[2] != null) ctx = new Context(args[2]); + * assert args.length == 2; + * error = toError(args[0]); + * if (args[1] != null) ctx = new Context(args[1]); * } * done.doneGetContext(token, error, ctx); * } * }.token; * } */ -public abstract class Command implements IChannel.ICommandListener { +public abstract class Command implements IErrorReport, IChannel.ICommandListener { private final IService service; private final String command; @@ -60,6 +66,8 @@ public abstract class Command implements IChannel.ICommandListener { private boolean done; + private static final SimpleDateFormat timestamp_format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + public Command(IChannel channel, IService service, String command, Object[] args) { this.service = service; this.command = command; @@ -131,28 +139,104 @@ public abstract class Command implements IChannel.ICommandListener { return buf.toString(); } - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked" }) public static String toErrorString(Object data) { - if (data instanceof String) { - return (String)data; + if (data == null) return null; + Map<String,Object> map = (Map<String,Object>)data; + String fmt = (String)map.get(ERROR_FORMAT); + if (fmt != null) { + Collection<Object> c = (Collection<Object>)map.get(ERROR_PARAMS); + if (c != null) return new MessageFormat(fmt).format(c.toArray()); + return fmt; + } + Number code = (Number)map.get(ERROR_CODE); + if (code != null) { + if (code.intValue() == TCF_ERROR_OTHER) { + String alt_org = (String)map.get(ERROR_ALT_ORG); + Number alt_code = (Number)map.get(ERROR_ALT_CODE); + if (alt_org != null && alt_code != null) { + return alt_org + " Error " + alt_code; + } + } + return "TCF Error " + code; + } + return "Invalid error report format"; + } + + private void appendErrorProps(StringBuffer bf, Map<String,Object> map) { + Number time = (Number)map.get(ERROR_TIME); + Number code = (Number)map.get(ERROR_CODE); + String service = (String)map.get(ERROR_SERVICE); + Number severity = (Number)map.get(ERROR_SEVERITY); + Number alt_code = (Number)map.get(ERROR_ALT_CODE); + String alt_org = (String)map.get(ERROR_ALT_ORG); + if (time != null) { + bf.append('\n'); + bf.append("Time: "); + bf.append(timestamp_format.format(new Date(time.longValue()))); + } + if (severity != null) { + bf.append('\n'); + bf.append("Severity: "); + bf.append(toErrorString(map)); + switch (severity.intValue()) { + case SEVERITY_ERROR: bf.append("Error"); + case SEVERITY_FATAL: bf.append("Fatal"); + case SEVERITY_WARNING: bf.append("Warning"); + default: bf.append("Unknown"); + } } - else if (data != null) { - Map<String,Object> map = (Map<String,Object>)data; - Collection<Object> c = (Collection<Object>)map.get("params"); - return new MessageFormat((String)map.get("format")).format(c.toArray()); + bf.append('\n'); + bf.append("Error text: "); + bf.append(toErrorString(map)); + bf.append('\n'); + bf.append("Error code: "); + bf.append(code); + if (service != null) { + bf.append('\n'); + bf.append("Service: "); + bf.append(service); + } + if (alt_code != null) { + bf.append('\n'); + bf.append("Alt code: "); + bf.append(alt_code); + if (alt_org != null) { + bf.append('\n'); + bf.append("Alt org: "); + bf.append(alt_org); + } } - return null; } - public Exception toError(Object code, Object data) { - int error_code = ((Number)code).intValue(); - if (error_code == 0) return null; + @SuppressWarnings("unchecked") + public Exception toError(Object data) { + if (data == null) return null; + Map<String,Object> map = (Map<String,Object>)data; String cmd = getCommandString(); if (cmd.length() > 72) cmd = cmd.substring(0, 72) + "..."; - return new Exception( - "TCF command exception:" + - "\nCommand: " + cmd + - "\nException: " + toErrorString(data) + - "\nError code: " + code); + StringBuffer bf = new StringBuffer(); + bf.append("TCF command error:"); + bf.append('\n'); + bf.append("Command: "); + bf.append(cmd); + appendErrorProps(bf, map); + Exception x = new Exception(bf.toString()); + Object caused_by = map.get(ERROR_CAUSE_BY); + if (caused_by != null) x.initCause(toNestedError(caused_by)); + return x; + } + + @SuppressWarnings("unchecked") + private Exception toNestedError(Object data) { + if (data == null) return null; + Map<String,Object> map = (Map<String,Object>)data; + StringBuffer bf = new StringBuffer(); + bf.append("TCF error:"); + appendErrorProps(bf, map); + Exception x = new Exception(bf.toString()); + Object caused_by = map.get(ERROR_CAUSE_BY); + if (caused_by != null) x.initCause(toNestedError(caused_by)); + return x; } } diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/IErrorReport.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/IErrorReport.java new file mode 100644 index 000000000..03146938c --- /dev/null +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/IErrorReport.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems, Inc. 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tm.tcf.protocol; + +/** + * This interface defines TCF standard format of error reports. + */ +public interface IErrorReport { + + /** Error report attribute names */ + public static final String + ERROR_CODE = "Code", // integer + ERROR_TIME = "Time", // integer + ERROR_SERVICE = "Service", // string + ERROR_FORMAT = "Format", // string + ERROR_PARAMS = "Params", // array + ERROR_SEVERITY = "Severity", // integer + ERROR_ALT_CODE = "AltCode", // integer + ERROR_ALT_ORG = "AltOrg", // string + ERROR_CAUSE_BY = "CausedBy"; // object + + /** Error severity codes */ + public static final int + SEVERITY_ERROR = 0, + SEVERITY_WARNING = 1, + SEVERITY_FATAL = 2; + + /** Error code ranges */ + public static final int + /** Standard TCF code range */ + CODE_STD_MIN = 0, + CODE_STD_MAX = 0xffff, + + /** Service specific codes. Decoding requires service ID. */ + CODE_SERVICE_SPECIFIC_MIN = 0x10000, + CODE_SERVICE_SPECIFIC_MAX = 0x1ffff, + + /** Reserved codes - will never be used by the TCF standard */ + CODE_RESERVED_MIN = 0x20000, + CODE_RESERVED_MAX = 0x2ffff; + + /** Standard TCF error codes */ + public static final int + TCF_ERROR_OTHER = 1, + TCF_ERROR_JSON_SYNTAX = 2, + TCF_ERROR_PROTOCOL = 3, + TCF_ERROR_BUFFER_OVERFLOW = 4, + TCF_ERROR_CHANNEL_CLOSED = 5, + TCF_ERROR_COMMAND_CANCELLED = 6, + TCF_ERROR_UNKNOWN_PEER = 7, + TCF_ERROR_BASE64 = 8, + TCF_ERROR_EOF = 9, + TCF_ERROR_ALREADY_STOPPED = 10, + TCF_ERROR_ALREADY_EXITED = 11, + TCF_ERROR_ALREADY_RUNNING = 12, + TCF_ERROR_ALREADY_ATTACHED = 13, + TCF_ERROR_IS_RUNNING = 14, + TCF_ERROR_INV_DATA_SIZE = 15, + TCF_ERROR_INV_CONTEXT = 16, + TCF_ERROR_INV_ADDRESS = 17, + TCF_ERROR_INV_EXPRESSION = 18, + TCF_ERROR_INV_FORMAT = 19, + TCF_ERROR_INV_NUMBER = 20, + TCF_ERROR_INV_DWARF = 21, + TCF_ERROR_SYM_NOT_FOUND = 22, + TCF_ERROR_UNSUPPORTED = 23; +} diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/JSON.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/JSON.java index f5000fed5..7403cdcbd 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/JSON.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/JSON.java @@ -357,7 +357,8 @@ public class JSON { private static Object[] readSequence() throws IOException { List<Object> l = new ArrayList<Object>(); while (cur_ch >= 0) { - l.add(readNestedObject()); + if (cur_ch == 0) l.add(null); + else l.add(readNestedObject()); if (cur_ch != 0) error("missing \\0 terminator"); read(); } @@ -539,6 +540,7 @@ public class JSON { public static Object parseOne(String s) throws IOException { assert Protocol.isDispatchThread(); + if (s.length() == 0) return null; reader = new StringReader(s); err_buf_pos = 0; err_buf_cnt = 0; @@ -550,6 +552,7 @@ public class JSON { public static Object parseOne(byte[] b) throws IOException { assert Protocol.isDispatchThread(); + if (b.length == 0) return null; reader = new InputStreamReader(new ByteArrayInputStream(b), "UTF8"); err_buf_pos = 0; err_buf_cnt = 0; |