prof18 / RSS-Parser

A Kotlin Multiplatform library to parse a RSS Feed

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Pulling Crashes on second pull

hisbaan opened this issue · comments

Describe the bug
My team and I are writing an RSS reader and are using this library to do so. The project is here: https://github.com/tminions/binocularss. When we call the getChannel method the first time, it works. But calling it a second time leads to a crash on every single feed we have tried it on. This may very well be a user-error so any help would be appreciated. This is the stack trace we receive for this feed:

D/RSSParser: Returning data from network
W/ons.binoculars: Accessing hidden method Ldalvik/system/CloseGuard;->get()Ldalvik/system/CloseGuard; (unsupported,core-platform-api, reflection, allowed)
W/ons.binoculars: Accessing hidden method Ldalvik/system/CloseGuard;->open(Ljava/lang/String;)V (unsupported,core-platform-api, reflection, allowed)
    Accessing hidden method Ldalvik/system/CloseGuard;->warnIfOpen()V (unsupported,core-platform-api, reflection, allowed)
W/ons.binoculars: Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setUseSessionTickets(Z)V (max-target-q,core-platform-api, reflection, denied)
W/ons.binoculars: Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setUseSessionTickets(Z)V (max-target-q,core-platform-api, reflection, denied)
    Accessing hidden method Lcom/android/org/conscrypt/AbstractConscryptSocket;->setUseSessionTickets(Z)V (max-target-q, reflection, denied)
    Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setHostname(Ljava/lang/String;)V (max-target-q,core-platform-api, reflection, denied)
    Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setHostname(Ljava/lang/String;)V (max-target-q,core-platform-api, reflection, denied)
    Accessing hidden method Lcom/android/org/conscrypt/AbstractConscryptSocket;->setHostname(Ljava/lang/String;)V (max-target-q, reflection, denied)
    Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V (max-target-q,core-platform-api, reflection, denied)
    Accessing hidden method Lcom/android/org/conscrypt/AbstractConscryptSocket;->setAlpnProtocols([B)V (max-target-q, reflection, denied)
W/ons.binoculars: Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B (max-target-q,core-platform-api, reflection, denied)
W/ons.binoculars: Accessing hidden method Lcom/android/org/conscrypt/AbstractConscryptSocket;->getAlpnSelectedProtocol()[B (max-target-q, reflection, denied)
W/ons.binoculars: Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setUseSessionTickets(Z)V (max-target-q,core-platform-api, reflection, denied)
W/ons.binoculars: Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setUseSessionTickets(Z)V (max-target-q,core-platform-api, reflection, denied)
    Accessing hidden method Lcom/android/org/conscrypt/AbstractConscryptSocket;->setUseSessionTickets(Z)V (max-target-q, reflection, denied)
    Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setHostname(Ljava/lang/String;)V (max-target-q,core-platform-api, reflection, denied)
    Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setHostname(Ljava/lang/String;)V (max-target-q,core-platform-api, reflection, denied)
    Accessing hidden method Lcom/android/org/conscrypt/AbstractConscryptSocket;->setHostname(Ljava/lang/String;)V (max-target-q, reflection, denied)
    Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V (max-target-q,core-platform-api, reflection, denied)
    Accessing hidden method Lcom/android/org/conscrypt/AbstractConscryptSocket;->setAlpnProtocols([B)V (max-target-q, reflection, denied)
W/ons.binoculars: Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B (max-target-q,core-platform-api, reflection, denied)
    Accessing hidden method Lcom/android/org/conscrypt/AbstractConscryptSocket;->getAlpnSelectedProtocol()[B (max-target-q, reflection, denied)
W/System.err: org.xmlpull.v1.XmlPullParserException: unterminated entity ref (position:TEXT @123:410 in java.io.InputStreamReader@b313a78) 
        at com.android.org.kxml2.io.KXmlParser.readEntity(KXmlParser.java:1220)
        at com.android.org.kxml2.io.KXmlParser.readValue(KXmlParser.java:1402)
        at com.android.org.kxml2.io.KXmlParser.next(KXmlParser.java:393)
        at com.android.org.kxml2.io.KXmlParser.next(KXmlParser.java:313)
        at com.prof.rssparser.core.CoreXMLParser.parseXML(CoreXMLParser.kt:238)
W/System.err:     at com.prof.rssparser.enginecoroutine.CoroutineEngine$parseXML$2.invokeSuspend(CoroutineEngine.kt:20)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)

Nothing from the stack trace is pointing to our code so I'm inclined to believe that it's either the way we implemented your code or the RSS-parser library itself. I don't think it's the feed as pulling the first time works perfectly. I've also tried to disable caching as that isn't strictly necessary for our use case, but that had no effect.

The link of the RSS Feed:
Every RSS feed we have tested is causing this issue. One specific feed for debugging purposes is https://raw.githubusercontent.com/prof18/RSS-Parser/adacf43fb5ea906c5394e59c5c61997baf15bf6d/rssparser/src/test/resources/feed-test-unexpected-token.xml

Thank you in advance for any help!

Hi,
I wasn't able to reproduce the issue neither with a test nor with the sample app (that calls again getChannel with the pull to refresh). If you want you can link me to the branch of your project so I can test it out.

Hi, thank you for the prompt response!
It's likely then a problem with our implementation. The main branch has some sample feeds added by default and hitting the "Update RSS" button twice will cause the errors on the second run. It doesn't crash the app as it's in a try-catch but it does print the stack trace in the console. On the add-feed branch, if you add a feed and then update it again (after the initial update is called by adding it) then you will get the same output as above. This is my first time working with coroutines, kotlin, and even asynchronous code so I may be doing things very wrong haha. Your function is called from the MainActivity by a function called updateRss which then calls a function in a ViewModel that then calls your function (along with others to convert to our datatypes and merge previously saved feeds with the ones your function returns so no articles are lost). The code may be a bit of a mess since this is obviously very early-stage development so let me know if you can't decipher why I've done something. Thank you again for being so helpful! :)

Don't worry, we all have started from the beginning! :)

Anyway, the error happens because when you click the second time in the "Update RSS", you are passing to the Parser URLs that are not RSS feeds, for example http://www.cbc.ca/news/?cmp=rss and https://www.androidauthority.com :)

If you put a breakpoint on line 36 of the PullFeed ViewModel, you'll discover the mistake!

I'm closing the issue since it's not a bug of the library, but feel free to comment if you have any other questions!

Oh wow! What a simple lapse of logic. Thank you so much! :) I really appreciate it (and so does the rest of my team!)