dvankley / firefly-plaid-connector-2

Connector to pull Plaid financial data into the Firefly finance tool
GNU General Public License v3.0
96 stars 15 forks source link

Failed to convert personal finance category to enum #107

Closed xCJPECKOVERx closed 3 months ago

xCJPECKOVERx commented 3 months ago

When running the connector, it fails after fetching the transactions from plaid and in the middle of processing to Firefly. After the following error, the app restarts:

2024-07-15T21:19:14.704Z DEBUG 1 --- [ main] n.d.f.transactions.TransactionConverter : Batch sync converting Plaid transactions to Firefly transactions 2024-07-15T21:19:14.738Z ERROR 1 --- [ main] o.s.boot.SpringApplication : Application run failed java.lang.IllegalArgumentException: Failed to convert personal finance category PersonalFinanceCategory(primary=GENERAL_MERCHANDISE, detailed=GENERAL_SERVICES_EDUCATION) to enum at net.djvk.fireflyPlaidConnector2.api.plaid.models.PersonalFinanceCategory.toEnum(PersonalFinanceCategory.kt:54) ~[classes/:1.1.2] at net.djvk.fireflyPlaidConnector2.transactions.TransactionConverter.sortByPairsBatched$suspendImpl(TransactionConverter.kt:297) ~[classes/:1.1.2] at net.djvk.fireflyPlaidConnector2.transactions.TransactionConverter.sortByPairsBatched(TransactionConverter.kt) ~[classes/:1.1.2] at net.djvk.fireflyPlaidConnector2.transactions.TransactionConverter.convertBatchSync$suspendImpl(TransactionConverter.kt:137) ~[classes/:1.1.2] at net.djvk.fireflyPlaidConnector2.transactions.TransactionConverter.convertBatchSync(TransactionConverter.kt) ~[classes/:1.1.2] at net.djvk.fireflyPlaidConnector2.sync.BatchSyncRunner$run$1.invokeSuspend(BatchSyncRunner.kt:123) ~[classes/:1.1.2] at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) ~[kotlin-stdlib-1.9.22.jar:1.9.22-release-704] at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104) ~[kotlinx-coroutines-core-jvm-1.8.1.jar:na] at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:277) ~[kotlinx-coroutines-core-jvm-1.8.1.jar:na] at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:95) ~[kotlinx-coroutines-core-jvm-1.8.1.jar:na] at kotlinx.coroutines.BuildersKtBuildersKt.runBlocking(Builders.kt:69) ~[kotlinx-coroutines-core-jvm-1.8.1.jar:na] at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source) ~[kotlinx-coroutines-core-jvm-1.8.1.jar:na] at kotlinx.coroutines.BuildersKtBuildersKt.runBlocking$default(Builders.kt:48) ~[kotlinx-coroutines-core-jvm-1.8.1.jar:na] at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source) ~[kotlinx-coroutines-core-jvm-1.8.1.jar:na] at net.djvk.fireflyPlaidConnector2.sync.BatchSyncRunner.run(BatchSyncRunner.kt:55) ~[classes/:1.1.2] at net.djvk.fireflyPlaidConnector2.FireflyPlaidConnector2Application.appReady(FireflyPlaidConnector2Application.kt:23) ~[classes/:1.1.2] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na] at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:365) ~[spring-context-6.1.8.jar:6.1.8] at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:237) ~[spring-context-6.1.8.jar:6.1.8] at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:168) ~[spring-context-6.1.8.jar:6.1.8] at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185) ~[spring-context-6.1.8.jar:6.1.8] at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178) ~[spring-context-6.1.8.jar:6.1.8] at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156) ~[spring-context-6.1.8.jar:6.1.8] at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:451) ~[spring-context-6.1.8.jar:6.1.8] at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:384) ~[spring-context-6.1.8.jar:6.1.8] at org.springframework.boot.context.event.EventPublishingRunListener.ready(EventPublishingRunListener.java:109) ~[spring-boot-3.3.0.jar:3.3.0] at org.springframework.boot.SpringApplicationRunListeners.lambda$ready$6(SpringApplicationRunListeners.java:80) ~[spring-boot-3.3.0.jar:3.3.0] at java.base/java.lang.Iterable.forEach(Unknown Source) ~[na:na] at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118) ~[spring-boot-3.3.0.jar:3.3.0] at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112) ~[spring-boot-3.3.0.jar:3.3.0] at org.springframework.boot.SpringApplicationRunListeners.ready(SpringApplicationRunListeners.java:80) ~[spring-boot-3.3.0.jar:3.3.0] at org.springframework.boot.SpringApplication.run(SpringApplication.java:349) ~[spring-boot-3.3.0.jar:3.3.0] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.0.jar:3.3.0] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.0.jar:3.3.0] at net.djvk.fireflyPlaidConnector2.FireflyPlaidConnector2ApplicationKt.main(FireflyPlaidConnector2Application.kt:31) ~[classes/:1.1.2] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na] at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:91) ~[workspace/:na] at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:53) ~[workspace/:na] at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:58) ~[workspace/:na]

dvankley commented 3 months ago

That seems like a bug on the Plaid side to me. Such things are not unheard of. I guess I'll do another special-case fix for this.

xCJPECKOVERx commented 3 months ago

Fair enough, appreciate the help 👍 Any way of maybe catching such errors and skipping the transaction instead of a full crash? I guess a crash forces eyss on the issue at least.

dvankley commented 3 months ago

Yeah, the idea is that this "should never happen." The two times I've seen this, the detailed value has been correct; it's just been primary that's a valid value, but not one that matches detailed. I've shipped a fix in https://github.com/dvankley/firefly-plaid-connector-2/commit/edde02a988c6cd3bb0222600755d6eb59d8cca07 that should hopefully take care of that class of bug going forward.

xCJPECKOVERx commented 3 months ago

Awesome, really appreciate the quick update. Unfortunately, I accidentally ran through the non-production quota, so I'll have to wait for full access before I can test again. I'll update here if I come across similar Plaid errors again.