The following code listing (Clipboard.mxml) shows a simple MXML application that demonstrates the utility of the
System.setClipboard(String)
method.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:flash.display="flash.display.*"
width="500" height="300"
applicationComplete="breakMe();">
<mx:Script>
<![CDATA[
/**
* To compile solely this Flex application from the command line, use
* mxmlc -strict=true Clipboard.mxml
*
* This application demonstrates use of the flash.system.System.setClipboard()
* function. The application intentionally tries to access an unavailable
* HTTPService so that the application's default fault handler is invoked and
* that invoked fault handler then puts its fault message on the clipboard.
*/
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.utils.ObjectUtil;
/**
* Handle successful result of web service or HTTP service associated with
* this result handler.
*
* @param aResultEvent Successful event.
*/
private function resultHandler(aResultEvent:ResultEvent):void
{
trace( "Successfully returned from "
+ aResultEvent.currentTarget.toString() );
}
/**
* Handle fault result of web service or HTTP service associated with this
* fault handler.
*
* @param aFaultEvent Fault event.
*/
private function faultHandler(aFaultEvent:FaultEvent):void
{
const faultEventTarget:String = ObjectUtil.toString(aFaultEvent.currentTarget);
const faultErrorId:int = aFaultEvent.fault.errorID;
const faultErrorCode:String = aFaultEvent.fault.faultCode;
const faultErrorDetail:String = aFaultEvent.fault.faultDetail;
const faultString:String = aFaultEvent.fault.faultString;
const faultMessage:String = aFaultEvent.fault.message;
const faultName:String = aFaultEvent.fault.name;
const faultErrorString:String =
"Fault " + faultErrorId + " (" + faultName + "):\n"
+ "[" + faultErrorCode + "]\n\n"
+ "FAULT MESSAGE: " + faultMessage + "\n\n"
+ "FAULT DETAILS: " + faultErrorDetail + "\n\n"
+ "FAULT STRING: " + faultString;;
const faultVerboseErrorString:String =
faultErrorString + "\n\n" + "FAULT ON TARGET:\n" + faultEventTarget;
trace(faultVerboseErrorString);
Alert.show(faultErrorString, "Intentional Fault Occurred");
flash.system.System.setClipboard(faultVerboseErrorString);
}
/**
* Function intended to intentionally call a non-existent HTTP Service to
* lead to its fault handler being invoked.
*/
private function breakMe():void
{
brokenService.send();
}
]]>
</mx:Script>
<mx:HTTPService id="brokenService"
resultFormat="e4x"
url="http://marxsoftware.blogspot.com/"
result="resultHandler(event);"
fault="faultHandler(event);" />
</mx:Application>
In the above code listing, I intentionally caused a fault handler to be invoked when the specified HTTPService could not access the provided URL. I took advantage of the information associated with a Fault for all forms of error output (trace(), Alert, and clipboard), but the information on the "current target" associated with the fault event is too verbose for the Alert. Therefore, I only included that information in the trace() and set it to the clipboard. Because the trace output may not always be available (such as when the application is not executed in a Flash Debug Player or a debugger is not connected), it is handy to have this same information sitting in my clipboard waiting for me to paste it into my favorite text editor or IDE.
I intentionally used a different
toString()
method in the result handler than I used in the fault handler. The toString
called directly on ResultEvent.currentTarget only outputs a single line of information (essentially identifying the current target as an HTTPService). The ObjectUtil.toString()
applied to the FaultEvent.currentTarget
supplies significantly more detail and that is why its output needed to not be placed in the alert. I have compared the inherited Object.toString
to the static ObjectUtil.toString(Object)
in greater detail in a previous blog entry.A screen capture of the output of this forced error is shown next:
This Alert pop-up was intentionally kept rather small by not including the lengthy target information in the output. However, that target information was included in the
trace()
call and to the clipboard. I cannot really show it here in a way that does it justice, but a very handy thing I can do at this point is to open a text editor and simply "paste" (CTRL-V, "Paste" option, etc.) into the editor. The text shown next will be inserted despite the fact that I never did a "copy" explicitly.
Fault 0 (Error):
[Channel.Security.Error]
FAULT MESSAGE: faultCode:Channel.Security.Error faultString:'Security error accessing url' faultDetail:'Destination: DefaultHTTP'
FAULT DETAILS: Destination: DefaultHTTP
FAULT STRING: Security error accessing url
FAULT ON TARGET:
(mx.rpc.http.mxml::HTTPService)#0
channelSet = (mx.messaging::ChannelSet)#1
channelIds = (Array)#2
[0] "direct_http_channel"
clustered = false
configured = false
connected = true
currentChannel = (mx.messaging.channels::DirectHTTPChannel)#3
channelSets = (Array)#4
[0] (mx.messaging::ChannelSet)#1
connected = true
connectTimeout = -1
endpoint = "http:"
failoverURIs = (Array)#5
id = "direct_http_channel"
protocol = "http"
reconnecting = false
requestTimeout = -1
uri = ""
messageAgents = (Array)#6
[0] (mx.rpc::AsyncRequest)#7
channelSet = (mx.messaging::ChannelSet)#1
clientId = "DirectHTTPChannel0"
connected = true
defaultHeaders = (null)
destination = "DefaultHTTP"
id = "E671BD31-DE99-42D6-7453-8F6F1FE32BC4"
requestTimeout = -1
session = (null)
subtopic = ""
concurrency = "multiple"
contentType = "application/x-www-form-urlencoded"
destination = "DefaultHTTP"
headers = (Object)#8
lastResult = (null)
makeObjectsBindable = true
method = "GET"
request = (Object)#9
requestTimeout = -1
resultFormat = "e4x"
rootURL = "file:///C:/flexExamples/Clipboard/Clipboard.swf"
showBusyCursor = false
url = "http://marxsoftware.blogspot.com/"
useProxy = false
xmlDecode = (null)
xmlEncode = (null)
As you can see, the information on the current target associated with the handled event is much more verbose than the fault information itself. Rather than having to subject myself to so much text in the Alert window or having to try to view the trace output in a debugger window, it was nice to be able to simply paste it all into a favorite text editor. Note that I can always redirect trace output to a file, but this
setClipboard(String)
tactic is a nice backup in case I forget to do that or forget to run in the appropriate mode or simply do not want to deal with that effort.One other interesting observation is that
Fault.message
contains the contents of Fault.faultCode
, Fault.faultDetail
and Fault.faultString
. This means, of course, that you'd normally not need to output all four properties and could go with just Fault.message
to get the contents of the other three. The examples associated with the Flex 2 Language Reference documentation on the
flash.system.System
class show using a handy property of this class (totalMemory) and writing that to the clipboard with setClipboard(String)
.The section "Saving Text to the Clipboard" in the Programming ActionScript 3.0 System Class write-up is what originally gave me the idea of using the
flash.system.System.setClipboard(String)
method to place error and fault information in the clipboard for easy pasting. Thanks to the author(s) of that for a very useful idea!Finally, the documentation makes it very clear that there is no
getClipboard()
method because of security concerns associated with the ability to grab data off of a user's clipboard.
1 comment:
try to access the crossdomain.cml file with IE. you will find secure="true" for each domain entry & this is creating a problem. Add secure="false" in each URL to resolve this issue.
cross-domain-policy
allow-access-from domain="*" secure="false"
Post a Comment