Created
July 29, 2010 20:22
-
-
Save wolever/499129 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package serialization { | |
import flash.utils.ByteArray; | |
import utils.logger.Log; | |
/** | |
* Serializes 'obj'. If serialization fails, tries really hard to figure | |
* out what caused it to fail. | |
*/ | |
public function safeSerialize(obj:*):ByteArray { | |
var serialized:ByteArray = new ByteArray(); | |
try { | |
serialized.writeObject(obj); | |
} catch (e:*) { | |
if (e.errorID == 2004) { | |
Log.error("A 'parameter is invalid' error is raised when " + | |
"serializing an instance of a class which isn't " + | |
"tagged with [RemoteClass] but has a parent which " + | |
"is tagged with [RemoteClass]."); | |
Log.error(findInvalidField(obj)); | |
throw Error("safeSerialize: serialization failed. Check log for " + | |
"diagnostic messages."); | |
} else { | |
throw e; | |
} | |
} | |
serialized.position = 0; | |
return serialized; | |
} | |
} | |
import flash.utils.ByteArray; | |
import flash.utils.getQualifiedClassName; | |
import org.hamcrest.DiagnosingMatcher; | |
import flash.utils.Dictionary; | |
import mx.utils.ObjectUtil; | |
import utils.objKeys; | |
/** | |
* When 'obj' is an instance which can't be serialized, try to figure | |
* out which field is causing problems. | |
*/ | |
function findInvalidField(obj:*, chain:Array=null, seen:Dictionary=null):String { | |
if (chain == null) | |
chain = []; | |
if (seen == null) | |
seen = new Dictionary(); | |
// Objects we have seen - we know these can't be serialized | |
seen[obj] = true; | |
// Get the version of the object which the serializer will see, then | |
// iterate over its fields, trying to find the field which can't | |
// be serialized. | |
var field:String; | |
var data:Object = obj; | |
for (field in data) { | |
// We can ignore values we know to be bad. | |
if (data[field] in seen) | |
continue; | |
if (!canSerialize(data[field])) | |
return findInvalidField(data[field], chain.concat(field), seen); | |
} | |
// If all of the fields of the object can be serailized, it means one | |
// of two things: | |
// - This object can't be serialized | |
// - The object is hiding a reference to something that can't be | |
// serialized. | |
var msg:String; | |
var type:String = getQualifiedClassName(obj); | |
var chainStr:String = chain.join("."); | |
msg = "Field '" + chainStr + "' of the serialized object could not " + | |
"be serialized.\n" + | |
"It is of type: " + type + "\n" + | |
"NB: It's likely that this object is fine, and it's " + | |
"some child instance that is causing the problems.\n" + | |
"The other instances which could not be serialized are:\n" + | |
" " + objKeys(seen).join("\n ") + "\n" + | |
"(note: this is only a guess - it may be incorrect)"; | |
return msg; | |
} | |
/** | |
* Can 'obj' be serialized? | |
* Will do the right thing if 'obj' is an instance of Serializable. | |
*/ | |
function canSerialize(obj:*):Boolean { | |
var b:ByteArray = new ByteArray(); | |
var err:*; | |
try { | |
b.writeObject(obj); | |
return true; | |
} catch (e:*) { | |
err = e; | |
} | |
// This is the error we get when we can't serialize something | |
if (err is ArgumentError && err.errorID == 2004) | |
return false; | |
// Otherwise, re-throw the error | |
throw err; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment