OrchardCMS / OrchardCore

Orchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.
https://orchardcore.net
BSD 3-Clause "New" or "Revised" License
7.42k stars 2.39k forks source link

Workflow ScriptTask Error: Property 'map' of object is not a function #12043

Closed hyzx86 closed 2 years ago

hyzx86 commented 2 years ago

Script:

var userList=['admin']

log('Error',"userList:"+JSON.stringify(userList))
var getMailBoxParams=userList.map(x=>`'${x}'`);
var mailListResult=executeQuery("QueryUserEmailByUserName",{userNames:getMailBoxParams.join(',')})
var staticEmail=[{"Email":"HUARUI2219@QQ.COM"}] 
log('Error',"staticEmail map:"+JSON.stringify(staticEmail.map(x=>x.Email)))
log('Error',"mailListResult:"+JSON.stringify(mailListResult))
log('Error',"mailListResult:"+JSON.stringify(mailListResult.map(x=>x.Email)))

var allMailStr= mailListResult.map(x=>`${x.Email}`).join(";")
setProperty("mailList",allMailStr)
setOutcome('Done');

log output

> userList:["admin"] 
> staticEmail map:["xxx@QQ.COM"] 
> mailListResult:[{"Email":"xxx@QQ.COM"}] 
>ERROR|An unhandled error occurred while executing an activity. Workflow ID: '16883'. Activity: '446k3gcdes9xs00j9pxmmy6hnj', 'ScriptTask'. Putting the workflow in the faulted state. Jint.Runtime.JavaScriptException: Cannot read property 'map' of undefined
   at :9:67    at :9:67
hyzx86 commented 2 years ago

The above tests use the latest code, but the tests in version 1.2.0 are normal

image

hyzx86 commented 2 years ago
> log('Error',"mailListResult:"+mailListResult)
mailListResult:System.Collections.Generic.List`1[Newtonsoft.Json.Linq.JObject] 
hyzx86 commented 2 years ago

After ToArray, it can be output normally @sebastienros Is it a bug in Jint?

> log('Error',"mailListResult:"+mailListResult.ToArray().map(x=>x.Email))
["xxx@QQ.COM"] 
lampersky commented 2 years ago

After ToArray, it can be output normally @sebastienros Is it a bug in Jint?

@hyzx86 I don't think it is a bug in Jint. Please have a look at executeQuery implementation, it is returning IEnumerable<object> which for Scripting is just a regular object, not an array, that is why you can't access map method. As you've noticed by converting object to an array you were able to use map method. You could also use spread operator to achieve the same.

here is original "executeQuery" method: image

You can simply fix this, by returning an array:

image

(I've used Linq here, so please remember to add using System.Linq; )

hyzx86 commented 2 years ago

@lampersky Last year, I submitted a similar issue and created PR, which is the same as the code above, but the final solution is that orchardcore updated jint. After a period of time, there was no such problem, but the latest version reappeared. I don't know why

hyzx86 commented 2 years ago

https://github.com/sebastienros/jint/issues/1005

hyzx86 commented 2 years ago

@lampersky So your solution is to re inject an executeQuery implementation?

Just like this?

 services.AddSingleton<IGlobalMethodProvider, MyQueryGlobalMethodProvider>();

I tested this method, and it really works,

However, there will be two such methods in the system. I don't know whether it will cause unexpected problems

lampersky commented 2 years ago

I don't know whether it will cause unexpected problems

I would say you will also need to replace DefaultScriptingManager with your own implementation, where you can choose which method should be used. Orchard Core will accept many GlobalMethods with the same name, but you can't be 100% sure which one will be used inside JavaScriptEngine (IScriptingEngine).

Here you can see, my own module where I've duplicated one of exisiting GlobalMethod: image

and here you can see how those methods are registered within Jint.Engine, as you can see methods with the same name overwrite existing ones: image

@hyzx86 I hope that helps :)

hyzx86 commented 2 years ago

@lampersky Thanks for sharing I will to refer to your code to solve this problem,

@sebastienros At the same time, I submitted my replication test on Jint