Invocation target exception when calling api.User().Create()

I have used api.User().Create to create users in the past but it seems that something is broken now. I am using Samba POS version 5.5.6

I have run the following function calls:

api.UserRole(‘Employee’).Exists() → True
api.User(‘User 1’).Exists() → False
api.User(‘User 1’).Create(‘Employee’, ‘789456123’) → throws exception!

I have tested with different values for the password parameter. When using an integer I get:

Samba.Services.Implementations.ExpressionModule.Accessors.ApiService.JsUser.Create(string, string) has some invalid arguments

This makes me think that the function call is correct but something is failing internally

Is there any alternative to create users from JavaScript?

This is a related topic issuing a request for such functionality: https://forum.sambapos.com/t/jscript-api-addition-for-users/7340

Just a shot in the dark, but I’m wondering if it’s the dangling column that has caused issues before.

Can you add a user manually in management?

possibly related to

Also, see this post about wrapping a call in a try/catch - you’ll then be able to see the underlying framework exception.

  1. Yes, I can add a new user manually from management

  2. Thanks for pointing out the try/catch code. There seems to be a problem by not providing the Terminal. The user interface in management also enforces the “Mobile Client Terminal” and “Employee type” values

This is the exception output:

System.Data.SqlClient.SqlException (0x80131904): Cannot insert the value NULL into column ‘Terminal_Id’, table ‘SambaPOS5.dbo.Users’; column does not allow nulls. INSERT fails.
The statement has been terminated.
en System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) en System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction)
en System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
en System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
en System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
en System.Data.SqlClient.SqlDataReader.get_MetaData()
en System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
en System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
en System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) en System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) en System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) en System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) en System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) en System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<>c.<Reader>b__6_0(DbCommand t, DbCommandInterceptionContext1 c)
en System.Data.Entity.Infrastructure.Interception.InternalDispatcher1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func3 operation, TInterceptionContext interceptionContext, Action3 executing, Action3 executed)
en System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
en System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
en System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
en System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary2 identifierValues, List1 generatedValues)
en System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
ClientConnectionId:6ac25ea2-dc89-4106-8598-0515b12961a5
Error Number:515,State:2,Class:16Microsoft.ClearScript.ScriptEngineException: Se produjo una excepción en el destino de la invocación. —> System.Reflection.TargetInvocationException: Se produjo una excepción en el destino de la invocación. —> System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details. —> System.Data.Entity.Core.UpdateException: An error occurred while updating the entries. See the inner exception for details. —> System.Data.SqlClient.SqlException: Cannot insert the value NULL into column ‘Terminal_Id’, table ‘SambaPOS5.dbo.Users’; column does not allow nulls. INSERT fails.
The statement has been terminated.
en System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) en System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction)
en System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
en System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
en System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
en System.Data.SqlClient.SqlDataReader.get_MetaData()
en System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
en System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
en System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) en System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) en System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) en System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) en System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) en System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<>c.<Reader>b__6_0(DbCommand t, DbCommandInterceptionContext1 c)
en System.Data.Entity.Infrastructure.Interception.InternalDispatcher1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func3 operation, TInterceptionContext interceptionContext, Action3 executing, Action3 executed)
en System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
en System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
en System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
en System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary2 identifierValues, List1 generatedValues)
en System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
— Fin del seguimiento de la pila de la excepción interna —
en System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
en System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.<>c.b__21_0(UpdateTranslator ut)
en System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func2 updateFunction) en System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update() en System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__153_0() en System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
en System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
en System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass148_0.b__0()
en System.Data.Entity.Infrastructure.DbExecutionStrategy.Execute[TResult](Func1 operation) en System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction) en System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options) en System.Data.Entity.Internal.InternalContext.SaveChanges() --- Fin del seguimiento de la pila de la excepción interna --- en System.Data.Entity.Internal.InternalContext.SaveChanges() en System.Data.Entity.Internal.LazyInternalContext.SaveChanges() en System.Data.Entity.DbContext.SaveChanges() en Samba.Infrastructure.Data.SqlData.EFWorkspace.CommitChanges() en Samba.Persistance.Implementations.UserDao.AddUser(String name, String pinCode, Int32 userRoleId, String employeeId) en Samba.Services.Implementations.UserModule.UserServiceBase.AddUser(String name, String pinCode, Int32 userRoleId, String employeeId) en Samba.Services.Implementations.ExpressionModule.Accessors.ApiService.JsUser.Create(String roleName, String pinCode) --- Fin del seguimiento de la pila de la excepción interna --- en System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) en System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) en System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) en Microsoft.ClearScript.Util.InvokeHelpers.InvokeMethod(IHostInvokeContext context, Object target, MethodInfo method, Object[] args) en Microsoft.ClearScript.HostItem.MethodBindSuccess.Invoke(HostItem hostItem) en Microsoft.ClearScript.HostItem.InvokeMethod(String name, Type[] typeArgs, Object[] args, Object[] bindArgs) en Microsoft.ClearScript.HostItem.InvokeMethod(String name, Object[] args, Object[] bindArgs) en Microsoft.ClearScript.HostItem.InvokeHostMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean& isCacheable) en Microsoft.ClearScript.HostItem.InvokeMember(String name, BindingFlags invokeFlags, Object[] args, Object[] bindArgs, CultureInfo culture, Boolean bypassTunneling, Boolean& isCacheable) en Microsoft.ClearScript.HostItem.<>c__DisplayClass156_0.<InvokeReflectMember>b__0() en Microsoft.ClearScript.ScriptEngine.HostInvoke[T](Func1 func)
en Microsoft.ClearScript.Windows.WindowsScriptEngine.HostInvoke[T](Func1 func) --- Fin del seguimiento de la pila de la excepción interna --- en Microsoft.ClearScript.Windows.WindowsScriptItem.TryBindAndInvoke(DynamicMetaObjectBinder binder, Object[] args, Object& result) en Microsoft.ClearScript.ScriptItem.<>c__DisplayClass7_0.<TryWrappedBindAndInvoke>b__0() en Microsoft.ClearScript.Windows.WindowsScriptEngine.<>c__DisplayClass57_01.b__0()
en Microsoft.ClearScript.ScriptEngine.ScriptInvokeInternal[T](Func1 func) en Microsoft.ClearScript.ScriptEngine.ScriptInvoke[T](Func1 func)
en Microsoft.ClearScript.Windows.WindowsScriptEngine.ScriptInvoke[T](Func`1 func)
en Microsoft.ClearScript.ScriptItem.TryWrappedBindAndInvoke(DynamicMetaObjectBinder binder, Object wrappedArgs, Object& result)
en Microsoft.ClearScript.ScriptItem.TryWrappedInvokeOrInvokeMember(DynamicMetaObjectBinder binder, ParameterInfo parameters, Object args, Object& result)
en Microsoft.ClearScript.ScriptItem.TryInvoke(InvokeBinder binder, Object args, Object& result)
en CallSite.Target(Closure , CallSite , Object )
en System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1[T0](CallSite site, T0 arg0)
en Microsoft.ClearScript.HostFunctions.tryCatch(Object tryFunc, Object catchFunc, Object finallyFunc)

I have also tried checking the “Default terminal” property for a Terminal, but it did not help

I believe that this leaves the api.User().Create() function unusable until updated with a new parameter. Is there any alternative?

That api was quickly replaced with GraphQL it still exists but it wont be updated any further. That was the first attempt at an API long time ago.

Here’s an old script I used to create a user. You’d have to change it to work with setting a terminal id or whatever required field exist now. I would recommend a stored procedure so you could pass a terminal name then get the Id on a join.

function createUser(username, pin) {
    if (pin.length < 4) {
        dlg.ShowMessage("Pin must be at least 4 numbers");
    }

    q = "SELECT COUNT(*) FROM Users WHERE PinCode = '" + pin + "'";
    r = sql.Query(q).First;

    qq = "SELECT COUNT(*) FROM Users WHERE Name = '" + username + "'";
    rr = sql.Query(qq).First;

    if (r > 0) {
        dlg.ShowMessage("Error with Pin Code.\rPlease retry with different pin");
    }

    if (rr > 0) {
        dlg.ShowMessage("Duplicate user name found.Please retry");
    }

    if (r == 0 && rr == 0 && pin.length >= 4) {
        q = "INSERT INTO USERS (PinCode, Name, UserRole_Id) VALUES ('" + pin + "', '" + username + "', '2')";
        sql.Exec(q);

        dlg.ShowMessage("User created successfully");
    }
}
1 Like