sillsdev / sillsdev/languageforge-lexbox

MiniLcm SDK improve error handling

Open
#1,838 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

📖 MiniLcm
Dominant language
C#
Stars
9
Forks
8
Avg merge
2d 13h
Merged PRs (30d)
49

Description

Describe the feature
Right now most errors are just 500's, we should try to return better errors where possible, eg 404 when trying to delete something which doesn't exist.

Some examples of issues:
But post fails (500) is entry and sense ids are the same.

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66af00",
  "lexemeForm": { "en": "string" },
  "senses": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66af00",
      "gloss": { "en": "string" }
    }
  ]
}
[start:core] [1] [2025-07-22 10:05:45.101] [info]  [FwLiteWeb]: info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
[start:core] [1]       Request starting HTTP/1.1 POST http://localhost:29348/api/mini-lcm/FwData/asdf/entry - application/json 490
[start:core] [1]
[start:core] [1] [2025-07-22 10:05:45.102] [info]  [FwLiteWeb]: info: Microsoft.AspNetCore.Cors.Infrastructure.CorsService[4]
[start:core] [1]       CORS policy execution successful.
[start:core] [1] info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
[start:core] [1]       Executing endpoint 'HTTP: POST /api/mini-lcm/{projectType}/{projectCode}/entry => PostEntry'
[start:core] [1]
[start:core] [1] [2025-07-22 10:05:45.157] [info]  [FwLiteWeb]: info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
[start:core] [1]       Executed endpoint 'HTTP: POST /api/mini-lcm/{projectType}/{projectCode}/entry => PostEntry'
[start:core] [1]
[start:core] [1] [2025-07-22 10:05:45.159] [info]  [FwLiteWeb]: fail: Microsoft.AspNetCore.Server.Kestrel[13]
[start:core] [1]       Connection id "0HNE950FJPV5Q", Request id "0HNE950FJPV5Q:00000001": An unhandled exception was thrown by the application.
[start:core] [1]       System.InvalidCastException: Unable to cast object of type 'SIL.LCModel.DomainImpl.LexSense' to type 'SIL.LCModel.ILexEntry'.
[start:core] [1]          at SIL.LCModel.Infrastructure.Impl.RepositoryBase`1.GetObject(Guid id)
[start:core] [1]          at FwDataMiniLcmBridge.Api.FwDataMiniLcmApi.GetEntry(Guid id) in C:\Users\danie\paranext\languageforge-lexbox\backend\FwLite\FwDataMiniLcmBridge\Api\FwDataMiniLcmApi.cs:line 826
[start:core] [1]          at FwDataMiniLcmBridge.Api.FwDataMiniLcmApi.CreateEntry(Entry entry) in C:\Users\danie\paranext\languageforge-lexbox\backend\FwLite\FwDataMiniLcmBridge\Api\FwDataMiniLcmApi.cs:line 879
[start:core] [1]          at Microsoft.AspNetCore.Http.RequestDelegateFactory.<TaskOfTToValueTaskOfObject>g__ExecuteAwaited|91_0[T](Task`1 task)
[start:core] [1]          at FwLiteWeb.Routes.MiniLcmRoutes.<>c.<<MapMiniLcmRoutes>b__2_1>d.MoveNext() in C:\Users\danie\paranext\languageforge-lexbox\backend\FwLite\FwLiteWeb\Routes\MiniLcmRoutes.cs:line 94
[start:core] [1]       --- End of stack trace from previous location ---
[start:core] [1]          at Microsoft.AspNetCore.Http.RequestDelegateFactory.<ExecuteValueTaskOfObject>g__ExecuteAwaited|128_0(ValueTask`1 valueTask, HttpContext httpContext, JsonTypeInfo`1 jsonTypeInfo)
[start:core] [1]          at Microsoft.AspNetCore.Http.RequestDelegateFactory.<>c__DisplayClass101_2.<<HandleRequestBodyAndCompileRequestDelegateForJson>b__2>d.MoveNext()
[start:core] [1]       --- End of stack trace from previous location ---
[start:core] [1]          at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
[start:core] [1]          at FwLiteWeb.FwLiteWebServer.<>c.<<SetupAppServer>b__0_8>d.MoveNext() in C:\Users\danie\paranext\languageforge-lexbox\backend\FwLite\FwLiteWeb\FwLiteWebServer.cs:line 113
[start:core] [1]       --- End of stack trace from previous location ---
[start:core] [1]          at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
[start:core] [1]          at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
[start:core] [1]          at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
[start:core] [1]          at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
[start:core] [1]
[start:core] [1] [2025-07-22 10:05:45.161] [info]  [FwLiteWeb]: info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
[start:core] [1]       Request finished HTTP/1.1 POST http://localhost:29348/api/mini-lcm/FwData/asdf/entry - 500 0 - 60.3158ms

And post fails (500) if the writing system isn't found

{
  "lexemeForm": { "qaa": "string" },
  "senses": [
    {
      "gloss": { "en": "string" }
    }
  ]
}
[start:core] [1] [2025-07-22 10:24:49.527] [info]  [FwLiteWeb]: info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
[start:core] [1]       Request starting HTTP/1.1 POST http://localhost:29348/api/mini-lcm/FwData/asdf/entry - application/json 104
[start:core] [1]
[start:core] [1] [2025-07-22 10:24:49.527] [info]  [FwLiteWeb]: info: Microsoft.AspNetCore.Cors.Infrastructure.CorsService[4]
[start:core] [1]       CORS policy execution successful.
[start:core] [1] info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
[start:core] [1]       Executing endpoint 'HTTP: POST /api/mini-lcm/{projectType}/{projectCode}/entry => PostEntry'
[start:core] [1]
[start:core] [1] [2025-07-22 10:24:49.544] [info]  [FwLiteWeb]: info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
[start:core] [1]       Executed endpoint 'HTTP: POST /api/mini-lcm/{projectType}/{projectCode}/entry => PostEntry'
[start:core] [1]
[start:core] [1] [2025-07-22 10:24:49.616] [info]  [FwLiteWeb]: fail: Microsoft.AspNetCore.Server.Kestrel[13]
[start:core] [1]       Connection id "0HNE95CQAKVO7", Request id "0HNE95CQAKVO7:00000001": An unhandled exception was thrown by the application.
[start:core] [1]       MiniLcm.Exceptions.CreateObjectException: Failed to create entry Entry { Id = 4abf031d-3c73-4898-b367-787b87703f92, DeletedAt = , LexemeForm = qaa: string, CitationForm = {}, LiteralMeaning = {}, Senses = System.Collections.Generic.List`1[MiniLcm.Models.Sense], Note = {}, Components = System.Collections.Generic.List`1[MiniLcm.Models.ComplexFormComponent], ComplexForms = System.Collections.Generic.List`1[MiniLcm.Models.ComplexFormComponent], ComplexFormTypes = System.Collections.Generic.List`1[MiniLcm.Models.ComplexFormType], PublishIn = System.Collections.Generic.List`1[MiniLcm.Models.Publication] }
[start:core] [1]        ---> System.NullReferenceException: unable to find writing system with id 'qaa'
[start:core] [1]          at FwDataMiniLcmBridge.Api.LcmHelpers.GetWritingSystemHandle(LcmCache cache, WritingSystemId ws, Nullable`1 type) in C:\Users\danie\paranext\languageforge-lexbox\backend\FwLite\FwDataMiniLcmBridge\Api\LcmHelpers.cs:line 122
[start:core] [1]          at FwDataMiniLcmBridge.Api.FwDataMiniLcmApi.GetWritingSystemHandle(WritingSystemId ws, Nullable`1 type) in C:\Users\danie\paranext\languageforge-lexbox\backend\FwLite\FwDataMiniLcmBridge\Api\FwDataMiniLcmApi.cs:line 81
[start:core] [1]          at FwDataMiniLcmBridge.Api.LcmHelpers.SetString(ITsMultiString multiString, FwDataMiniLcmApi api, WritingSystemId ws, String value) in C:\Users\danie\paranext\languageforge-lexbox\backend\FwLite\FwDataMiniLcmBridge\Api\LcmHelpers.cs:line 175
[start:core] [1]          at FwDataMiniLcmBridge.Api.FwDataMiniLcmApi.UpdateLcmMultiString(ITsMultiString multiString, MultiString newMultiString) in C:\Users\danie\paranext\languageforge-lexbox\backend\FwLite\FwDataMiniLcmBridge\Api\FwDataMiniLcmApi.cs:line 1128
[start:core] [1]          at FwDataMiniLcmBridge.Api.FwDataMiniLcmApi.<>c__DisplayClass116_0.<CreateEntry>b__0() in C:\Users\danie\paranext\languageforge-lexbox\backend\FwLite\FwDataMiniLcmBridge\Api\FwDataMiniLcmApi.cs:line 840
[start:core] [1]          at SIL.LCModel.Infrastructure.UndoableUnitOfWorkHelper.Do(String undoText, String redoText, IActionHandler actionHandler, Action task)
[start:core] [1]          at SIL.LCModel.Infrastructure.UndoableUnitOfWorkHelper.DoUsingNewOrCurrentUOW(String undoText, String redoText, IActionHandler actionHandler, Action task)
[start:core] [1]          at FwDataMiniLcmBridge.Api.FwDataMiniLcmApi.CreateEntry(Entry entry) in C:\Users\danie\paranext\languageforge-lexbox\backend\FwLite\FwDataMiniLcmBridge\Api\FwDataMiniLcmApi.cs:line 834
[start:core] [1]          --- End of inner exception stack trace ---
[start:core] [1]          at FwDataMiniLcmBridge.Api.FwDataMiniLcmApi.CreateEntry(Entry entry) in C:\Users\danie\paranext\languageforge-lexbox\backend\FwLite\FwDataMiniLcmBridge\Api\FwDataMiniLcmApi.cs:line 876
[start:core] [1]          at Microsoft.AspNetCore.Http.RequestDelegateFactory.<TaskOfTToValueTaskOfObject>g__ExecuteAwaited|91_0[T](Task`1 task)
[start:core] [1]          at FwLiteWeb.Routes.MiniLcmRoutes.<>c.<<MapMiniLcmRoutes>b__2_1>d.MoveNext() in C:\Users\danie\paranext\languageforge-lexbox\backend\FwLite\FwLiteWeb\Routes\MiniLcmRoutes.cs:line 94
[start:core] [1]       --- End of stack trace from previous location ---
[start:core] [1]          at Microsoft.AspNetCore.Http.RequestDelegateFactory.<ExecuteValueTaskOfObject>g__ExecuteAwaited|128_0(ValueTask`1 valueTask, HttpContext httpContext, JsonTypeInfo`1 jsonTypeInfo)
[start:core] [1]          at Microsoft.AspNetCore.Http.RequestDelegateFactory.<>c__DisplayClass101_2.<<HandleRequestBodyAndCompileRequestDelegateForJson>b__2>d.MoveNext()
[start:core] [1]       --- End of stack trace from previous location ---
[start:core] [1]          at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
[start:core] [1]          at FwLiteWeb.FwLiteWebServer.<>c.<<SetupAppServer>b__0_8>d.MoveNext() in C:\Users\danie\paranext\languageforge-lexbox\backend\FwLite\FwLiteWeb\FwLiteWebServer.cs:line 113
[start:core] [1]       --- End of stack trace from previous location ---
[start:core] [1]          at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
[start:core] [1]          at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
[start:core] [1]          at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
[start:core] [1]          at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
[start:core] [1]
[start:core] [1] [2025-07-22 10:24:49.626] [info]  [FwLiteWeb]: info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
[start:core] [1]       Request finished HTTP/1.1 POST http://localhost:29348/api/mini-lcm/FwData/asdf/entry - 500 0 - 98.8904ms

And post fails (400) if the id string is not a valid guid

{
  "id": "not-a-guid",
  "lexemeForm": { "qaa": "string" },
  "senses": [
    {
      "gloss": { "en": "string" }
    }
  ]
}
[start:core] [1] [2025-07-22 10:30:57.999] [info]  [FwLiteWeb]: info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
[start:core] [1]       Request starting HTTP/1.1 POST http://localhost:29348/api/mini-lcm/FwData/asdf/entry - application/json 126
[start:core] [1]
[start:core] [1] [2025-07-22 10:30:58.002] [info]  [FwLiteWeb]: info: Microsoft.AspNetCore.Cors.Infrastructure.CorsService[4]
[start:core] [1]       CORS policy execution successful.
[start:core] [1] info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
[start:core] [1]       Executing endpoint 'HTTP: POST /api/mini-lcm/{projectType}/{projectCode}/entry => PostEntry'
[start:core] [1]
[start:core] [1] [2025-07-22 10:30:58.003] [info]  [FwLiteWeb]: info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
[start:core] [1]       Executed endpoint 'HTTP: POST /api/mini-lcm/{projectType}/{projectCode}/entry => PostEntry'
[start:core] [1] info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
[start:core] [1]       Request finished HTTP/1.1 POST http://localhost:29348/api/mini-lcm/FwData/asdf/entry - 400 0 - 4.8329ms

Originally posted by @imnasnainaec in https://github.com/sillsdev/languageforge-lexbox/issues/1833#issuecomment-3103014707

[!NOTE]
these were all run against FwData, not Harmony

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the MiniLcmRoutes.cs POST entry endpoint, then trace the cases in FwDataMiniLcmApi.cs and LcmHelpers.cs shown by the stack traces. Review how missing objects, duplicate IDs, missing writing systems, and invalid GUIDs currently become responses. Done means these cases return appropriate, informative HTTP errors instead of unexpected 500 responses, while preserving the existing 400 behavior for invalid GUID input.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api, backend, backend-api-design
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.