fluree / core

Fluree releases and public bug reports
0 stars 0 forks source link

Malformed create requests to fluree/server hang instead of returning an error [BUG] #99

Open zonotope opened 2 months ago

zonotope commented 2 months ago

Describe the bug Malformed or invalid create requests to fluree/server hang instead of returning an error

To Reproduce Steps to reproduce the behavior:

  1. Issue an invalid create request such as the following (note that the type of "ex:localizedString" is xsd:string and only rdf:langString is allowed for language tagged strings):
    {
    "@context": {
    "schema": "http://schema.org/",
    "ex": "http://example.org/"
    },
    "ledger": "test",
    "insert": {
    "@id": "ex:entity0",
    "@type": "ex:TestEntity",
    "schema:name": "Name 0",
    "schema:age": {
      "@type": "xsd:integer",
      "@value": 12
    },
    "ex:localalizedString": {
      "@type": "xsd:string",
      "@value": "localizedString",
      "@language": "en-CA"
    }
    }
    }

Expected behavior The user is notified of the invalid request with an error message explaining what's wrong instead of the system hanging.

Stack trace These errors come from the server logs:

14:18:26.282 [clojure-agent-send-off-pool-0] ERROR f.s.components.consensus-handler - "Unexpected error in processor function for event :ledger-create with message: @language cannot be used for values with a specified @type Error at idx: [\"ex:localizedString\"]"
clojure.lang.ExceptionInfo: @language cannot be used for values with a specified @type Error at idx: ["ex:localizedString"]
        at fluree.json_ld.impl.expand$wrap_error.invokeStatic(expand.cljc:300)
        at fluree.json_ld.impl.expand$wrap_error.invoke(expand.cljc:293)
        at fluree.json_ld.impl.expand$node_STAR_$fn__23232.invoke(expand.cljc:333)
        at fluree.json_ld.impl.expand$node_STAR_.invokeStatic(expand.cljc:331)
        at fluree.json_ld.impl.expand$node_STAR_.invoke(expand.cljc:315)
        at fluree.json_ld.impl.expand$node.invokeStatic(expand.cljc:384)
        at fluree.json_ld.impl.expand$node.invoke(expand.cljc:360)
        at fluree.json_ld.impl.expand$node.invokeStatic(expand.cljc:366)
        at fluree.json_ld.impl.expand$node.invoke(expand.cljc:360)
        at fluree.json_ld$expand.invokeStatic(json_ld.cljc:96)
        at fluree.json_ld$expand.invoke(json_ld.cljc:88)
        at fluree.db.query.fql.parse$parse_txn.invokeStatic(parse.cljc:642)
        at fluree.db.query.fql.parse$parse_txn.invoke(parse.cljc:629)
        at fluree.db.json_ld.transact$stage$fn__39171$state_machine__14611__auto____39180$fn__39183.invoke(transact.cljc:214)
        at fluree.db.json_ld.transact$stage$fn__39171$state_machine__14611__auto____39180.invoke(transact.cljc:212)
        at clojure.core.async.impl.ioc_macros$run_state_machine.invokeStatic(ioc_macros.clj:972)
        at clojure.core.async.impl.ioc_macros$run_state_machine.invoke(ioc_macros.clj:971)
        at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invokeStatic(ioc_macros.clj:976)
        at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invoke(ioc_macros.clj:974)
        at fluree.db.json_ld.transact$stage$fn__39171.invoke(transact.cljc:212)
        at clojure.lang.AFn.run(AFn.java:22)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at clojure.core.async.impl.concurrent$counted_thread_factory$reify__9575$fn__9576.invoke(concurrent.clj:29)
        at clojure.lang.AFn.run(AFn.java:22)
        at java.base/java.lang.Thread.run(Unknown Source)
Caused by: clojure.lang.ExceptionInfo: @language cannot be used for values with a specified @type
        at fluree.json_ld.impl.expand$throw_invalid_language.invokeStatic(expand.cljc:136)
        at fluree.json_ld.impl.expand$throw_invalid_language.invoke(expand.cljc:134)
        at fluree.json_ld.impl.expand$parse_node_value_map.invokeStatic(expand.cljc:187)
        at fluree.json_ld.impl.expand$parse_node_value_map.invoke(expand.cljc:177)
        at fluree.json_ld.impl.expand$fn__23174.invokeStatic(expand.cljc:215)
        at fluree.json_ld.impl.expand$fn__23174.invoke(expand.cljc:198)
        at clojure.lang.MultiFn.invoke(MultiFn.java:252)
        at fluree.json_ld.impl.expand$node_STAR_$fn__23232.invoke(expand.cljc:332)
        ... 23 common frames omitted
aaj3f commented 2 months ago

@zonotope I would even initially accept an error response with a less-than-perfect explanation (rather than an indefinite hang). Which is to say if our existing txn validation handling (e.g. malli etc) already could recognize the error and produce a useful report, then by all means, let's return that with the error, but if not, then just capturing some initial error and handling it rather than hanging would maybe be sufficient

zonotope commented 2 months ago

Agreed. The problem here is that I don't think the kind of superficial/syntax level validation that we could provide as our first line of defense in the http request handling with something like malli could catch a semantic/logical error like this. We will only know that this request is malformed after we begin parsing and executing the request itself, so it might take a little creativity to bubble that error that probably happens in the raft state machine back up to the user.