microsoft/ClearScript

Error: Binary format of the specified custom attribute was invalid

DavidBal opened this issue · 2 comments

Hi ClearScript Team,

i have the following code:

 [CustomAttribute("ResponseEmpty", ExportType = false)]
 public class ResponseEmpty
 {
     public bool ok { get; set; }
 }

 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
 public sealed class CustomAttribute: Attribute
 {
     public string ClassAlias { get; }

     public bool ExportType { get; set; } = true;

     public CustomAttribute(string classAlias)
     {
         ClassAlias = classAlias;
     }
 }

When i return a object from type ResponseEmpty to a V8Script, i get this exception:

Error: Binary format of the specified custom attribute was invalid.
       at V8ScriptEngine [internal]:1:896 -> Object.defineProperty(this,'EngineInternal',{value:(t=>{let e=t=>t.bind();function r(){return new this(...arguments)}let o=t.isHostObjectKey;delete t.isHostObjectKey;let n=t=>!!t&&!0===t[o],c=Promise,i=JSON,a=Symbol(),s=t.toJson;return delete t.toJson,Object.freeze({commandHolder:{},getCommandResult:e(t=>null==t?t:'function'!=typeof t.hasOwnProperty?'Module'===t[Symbol.toStringTag]?'[module]':'[external]':!0===t[o]?t:'function'!=typeof t.toString?'['+typeof t+']':t.toString()),strictEquals:e((t,e)=>t===e),invokeConstructor:e((t,e)=>{if('function'!=typeof t)throw Error('Function expected');return r.apply(t,Array.from(e))}),invokeMethod:e((t,e,r)=>{if('function'!=typeof e)throw Error('Function expected');return e.apply(t,Array.from(r))}),createPromise:e(function(){return new c(...arguments)}),isPromise:e(t=>t instanceof c),isHostObject:e(n),completePromiseWithResult:e((t,e,r)=>{try{e(t())}catch(o){r(o)}}),completePromise:e((t,e,r)=>{try{t(),e()}catch(o){r(o)}}),throwValue:e(t=>{throw t}),getStackTrace:e(()=>{try{throw Error('[stack trace]')}catch(t){return t.stack}}),toIterator:e(function*(t){try{for(;t.ScriptableMoveNext();)yield t.ScriptableCurrent}finally{t.ScriptableDispose()}}),toAsyncIterator:e(async function*(t){try{for(;await t.ScriptableMoveNextAsync();)yield t.ScriptableCurrent}finally{await t.ScriptableDisposeAsync()}}),getIterator:e(t=>t?.[Symbol.iterator]?.()),getAsyncIterator:e(t=>t?.[Symbol.asyncIterator]?.()),checkpoint:e(()=>{let e=t[a];if(e)throw e}),toJson:e((t,e)=>s?i.parse(s(t,e)):e),parseJson:e(t=>i.parse(t)),asyncGenerator:async function*(){}().constructor})})(this)});
   --- End of inner exception stack trace ---
   at Microsoft.ClearScript.V8.SplitProxy.V8SplitProxyNative.Invoke(Action`1 action)
   at Microsoft.ClearScript.V8.SplitProxy.V8ContextProxyImpl.InvokeWithLock(Action action)
   at Microsoft.ClearScript.V8.V8ScriptEngine.ScriptInvoke[T](Func`1 func)
   at Microsoft.ClearScript.V8.V8ScriptItem.InvokeMethod(Boolean marshalResult, String name, Object[] args)
   at Microsoft.ClearScript.V8.V8ScriptItem.InvokeMethod(String name, Object[] args)
   at Microsoft.ClearScript.V8.V8ScriptEngine.<>c__DisplayClass147_0.<Microsoft.ClearScript.JavaScript.IJavaScriptEngine.CreateTaskForPromise>b__1(Object error)
   --- Script error details follow ---
   Error: Binary format of the specified custom attribute was invalid.
       at V8ScriptEngine [internal]:1:896 -> Object.defineProperty(this,'EngineInternal',{value:(t=>{let e=t=>t.bind();function r(){return new this(...arguments)}let o=t.isHostObjectKey;delete t.isHostObjectKey;let n=t=>!!t&&!0===t[o],c=Promise,i=JSON,a=Symbol(),s=t.toJson;return delete t.toJson,Object.freeze({commandHolder:{},getCommandResult:e(t=>null==t?t:'function'!=typeof t.hasOwnProperty?'Module'===t[Symbol.toStringTag]?'[module]':'[external]':!0===t[o]?t:'function'!=typeof t.toString?'['+typeof t+']':t.toString()),strictEquals:e((t,e)=>t===e),invokeConstructor:e((t,e)=>{if('function'!=typeof t)throw Error('Function expected');return r.apply(t,Array.from(e))}),invokeMethod:e((t,e,r)=>{if('function'!=typeof e)throw Error('Function expected');return e.apply(t,Array.from(r))}),createPromise:e(function(){return new c(...arguments)}),isPromise:e(t=>t instanceof c),isHostObject:e(n),completePromiseWithResult:e((t,e,r)=>{try{e(t())}catch(o){r(o)}}),completePromise:e((t,e,r)=>{try{t(),e()}catch(o){r(o)}}),throwValue:e(t=>{throw t}),getStackTrace:e(()=>{try{throw Error('[stack trace]')}catch(t){return t.stack}}),toIterator:e(function*(t){try{for(;t.ScriptableMoveNext();)yield t.ScriptableCurrent}finally{t.ScriptableDispose()}}),toAsyncIterator:e(async function*(t){try{for(;await t.ScriptableMoveNextAsync();)yield t.ScriptableCurrent}finally{await t.ScriptableDisposeAsync()}}),getIterator:e(t=>t?.[Symbol.iterator]?.()),getAsyncIterator:e(t=>t?.[Symbol.asyncIterator]?.()),checkpoint:e(()=>{let e=t[a];if(e)throw e}),toJson:e((t,e)=>s?i.parse(s(t,e)):e),parseJson:e(t=>i.parse(t)),asyncGenerator:async function*(){}().constructor})})(this)});
   --- End of inner exception stack trace ---

The workaround for this exception is to change the code to the following:

 [CustomAttribute("ResponseEmpty", false)] //here
 public class ResponseEmpty
 {
     public bool ok { get; set; }
 }

 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
 public sealed class CustomAttribute: Attribute
 {
     public string ClassAlias { get; }

     public bool ExportType { get;  } = true;

     public CustomeAttribute(string classAlias)
     {
         ClassAlias = classAlias;
     }
     
     public CustomAttribute(string classAlias, bool exportType) //here
     {
         ClassAlias = classAlias;
         ExportType = exportType;
     }
 }

Thanks in advance.

Best regards,
David

Hi @DavidBal,

We're having trouble reproducing this issue. We can pass ResponseEmpty instances to script code – and instantiate ResponseEmpty in script code – without any problems. Can you provide a minimal sample? Also what .NET runtime are you using?

Thanks!

Please reopen this issue if you have additional information about this topic. Thank you!