Paypal commerce can't be installed, null reference exception

4 tháng cách đây
NopCommerce 4.80.2

I tried to install the plugin "paypal commerce" (the official integration)
but upon clicking "install" and restarting the shop, it throws an error
System.NullReferenceException: Object reference not set to an instance of an object.
   at Nop.Plugin.Payments.PayPalCommerce.Services.EventConsumer.GetAdminMenuItemAsync(IPlugin plugin) in C:\Repositories\nopCommerce_work\src\Plugins\Nop.Plugin.Payments.PayPalCommerce\Services\EventConsumer.cs:line 98
   at Nop.Web.Framework.Events.BaseAdminMenuCreatedEventConsumer.HandleEventAsync(AdminMenuCreatedEvent eventMessage)
   at Nop.Services.Events.EventPublisher.PublishAsync[TEvent](TEvent event)


I found the problem in the following:
in the class "EventPublisher.cs" there is a method "PublishAsync" that resolves all occurences of the event consumer for the event "GetAdminMenuItemAsync"
var consumers = EngineContext.Current.ResolveAll<IConsumer<TEvent>>().ToList();

foreach (var consumer in consumers)
{
    try
    {
        //try to handle published event
        await consumer.HandleEventAsync(@event);
...


and upon handling it in the class "BaseAdminMenuCreatedEventConsumer", method "HandleEventAsync"
does the following:
var plugin = await _pluginManager.LoadPluginBySystemNameAsync(PluginSystemName);

var newItem = await GetAdminMenuItemAsync(plugin);


what happened? The plugin is not installed yet so "var plugin" is null.
the class "EventConsumer", method "GetAdminMenuItemAsync" of the paypal commerce plugin is called nevertheless
and throws the "object reference not set" error at the methods first line "var descriptor = plugin.PluginDescriptor;"

I honestly don't understand why event consumers of not-installed plugins are loaded.
in my plugins.json there still is
"PluginNamesToInstall": [
  {
    "Item1": "Payments.PayPalCommerce",
    "Item2": "a29ff26f-de6a-45a5-b0de-b8894dd104d5"
  }
]


also: what is the item2? i did not find this guid anywhere else.
it's also not the project guid in the visual studio solution file.

this guid of item2 appears in the plugins.json in the development environment but also in the live environment (nopcommerce noSource 4.80.2)
4 tháng cách đây
i tried to quickfix it by adding
"if (plugin == null) return null;"
to the plugins "EventConsumer.GetAdminMenuItemAsync"

but now, after clicking on "install" on the plugins page, i get
the Plugin "Payments.PayPalCommerce" is not installed.

System.Exception: An error occurred executing the following sql:
CREATE TABLE [dbo].[PayPalToken] ([Id] INT NOT NULL IDENTITY(1,1), [CustomerId] INT NOT NULL, [VaultId] NVARCHAR(100), [VaultCustomerId] NVARCHAR(100), [TransactionId] NVARCHAR(100), [Title] NVARCHAR(200), [Expiration] NVARCHAR(100), [Type] NVARCHAR(100), [ClientId] NVARCHAR(200) NOT NULL, [IsPrimaryMethod] BIT NOT NULL, CONSTRAINT [PK_PayPalToken] PRIMARY KEY ([Id]))
The error was In der Datenbank ist bereits ein Objekt mit dem Namen "PayPalToken" vorhanden.

---> Microsoft.Data.SqlClient.SqlException (0x80131904): In der Datenbank ist bereits ein Objekt mit dem Namen "PayPalToken" vorhanden.
   at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, SqlCommand command, Boolean callerHasConnectionLock, Boolean asyncClose)
   at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at Microsoft.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean isAsync, Int32 timeout, Boolean asyncWrite)
   at Microsoft.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String methodName)
   at Microsoft.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at FluentMigrator.Runner.Processors.SqlServer.SqlServerProcessor.ExecuteNonQuery(String sql)
ClientConnectionId:514a8db6-d46c-4599-80b1-6d5e08b4f354
Fehlernummer (Error Number):2714,Status (State):6,Klasse (Class):16
   --- End of inner exception stack trace ---
   at FluentMigrator.Runner.Processors.ProcessorBase.ReThrowWithSql(Exception ex, String sql)
   at FluentMigrator.Runner.Processors.SqlServer.SqlServerProcessor.ExecuteNonQuery(String sql)
   at FluentMigrator.Runner.Processors.SqlServer.SqlServerProcessor.Process(String sql)
   at FluentMigrator.Runner.Processors.ProcessorBase.Process(CreateTableExpression expression)
   at FluentMigrator.Expressions.CreateTableExpression.ExecuteWith(IMigrationProcessor processor)
   at FluentMigrator.Runner.MigrationRunner.<>c__DisplayClass75_0.<ExecuteExpressions>b__1()
   at FluentMigrator.Runner.StopWatch.Time(Action action)
   at FluentMigrator.Runner.MigrationRunner.AnnounceTime(String message, Action action)
   at FluentMigrator.Runner.MigrationRunner.ExecuteExpressions(ICollection`1 expressions)
   at FluentMigrator.Runner.MigrationRunner.ExecuteMigration(IMigration migration, Action`2 getExpressions)
   at FluentMigrator.Runner.MigrationRunner.ApplyMigrationUp(IMigrationInfo migrationInfo, Boolean useTransaction)
   at FluentMigrator.Runner.MigrationRunner.Up(IMigration migration)
   at Nop.Data.Migrations.MigrationManager.ApplyUpMigration(IMigrationInfo migrationInfo, Boolean commitVersionOnly)
   at Nop.Data.Migrations.MigrationManager.ApplyUpMigrations(Assembly assembly, MigrationProcessType migrationProcessType, Boolean commitVersionOnly)
   at Nop.Services.Plugins.PluginService.InsertPluginData(Type pluginType, MigrationProcessType migrationProcessType)
   at Nop.Services.Plugins.PluginService.InstallPluginsAsync()
4 tháng cách đây
Hi!

I tried to reproduce the problem. Even though an error is written in the log, it does not interfere with the plugin's installation process. However, I created a task and will add the necessary changes so there is no error in the log.

Further to your questions:

1. event consumers are loaded from all plugins that are installed or should be installed at startup, that is, they are in the PluginNamesToInstall list. This is because, for such plugins, their assemblies are placed in the context at the start of the site
2. for the "PluginNamesToInstall" parameter:
    Item1 - system name of the plugin
    Item2 - user ID who initiated the installation
4 tháng cách đây
Also regarding the second exception, in all likelihood, the plugin was initially removed incorrectly, or another error occurred during installation, due to which the "PayPalToken" table already exists in the database, which is why this problem arises during a new installation. Just delete the table from the database manually
4 tháng cách đây
Hello Sergei,
thanks for the fast reply and the useful information.

Okay I get it, the events are registered/loaded from plugins that should be installed, too. great idea.

For reasearch purpose only, if someone encounters the same problem:
Now I understand what happened. together with the NopCommerce update (4.70.3 --> 4.80.2) I overwrote the paypal-plugin. But as I read you fully reworked the plugin and therefore, the new version had viewer files (dlls, dependencies?). As I just copied the new files into the plugins folder, there were some old files left, which lead to an error while installing.
I then ran "uninstall" on the plugin page (still with the frankenstein version, files of new and old version) which removed the plugin from "Plugins.json" but it did not drop the table.

after i dropped it manually, deleted the plugins' folder and installed it freshly, I worked instantly.

So I guess it's not neccessary to look further into this issue, Sergei.

Thanks for the help