Skip to content

Safe JSON serializer & content-length fix (issue with Routes in Revit French)#3161

Open
vinnividivicci wants to merge 4 commits intopyrevitlabs:developfrom
vinnividivicci:routes-http-bug-fix
Open

Safe JSON serializer & content-length fix (issue with Routes in Revit French)#3161
vinnividivicci wants to merge 4 commits intopyrevitlabs:developfrom
vinnividivicci:routes-http-bug-fix

Conversation

@vinnividivicci
Copy link

@vinnividivicci vinnividivicci commented Mar 4, 2026

Safe JSON serializer & content-length fix (issue with Routes in Revit French)

Description

Add a Unicode-safe JSON serializer (_safe_json_dumps) to handler.py to avoid json.dumps UnicodeDecodeError on IronPython by escaping non-ASCII as \uXXXX. Use json.dumps(..., ensure_ascii=True) with a fallback to _safe_json_dumps when encoding errors occur. Update HttpRequestHandler._write_response to always compute a bytes body, set a correct Content-Length header, skip duplicate Content-Length from response headers, and write the encoded body. Add unit tests covering response framing (Content-Length and body bytes) and Unicode-safe JSON serialization/parse_response behavior.


Checklist

Before submitting your pull request, ensure the following requirements are met:

  • Code follows the PEP 8 style guide.
  • Code has been formatted with Black using the command:
    pipenv run black {source_file_or_directory}
  • Changes are tested and verified to work as expected.

Related Issues

If applicable, link the issues resolved by this pull request:

  • Resolves #[issue number]

Additional Notes

Include any additional context, screenshots, or considerations for reviewers.


Thank you for contributing to pyRevit! 🎉

Add a Unicode-safe JSON serializer (_safe_json_dumps) to handler.py to avoid json.dumps UnicodeDecodeError on IronPython by escaping non-ASCII as \uXXXX. Use json.dumps(..., ensure_ascii=True) with a fallback to _safe_json_dumps when encoding errors occur. Update HttpRequestHandler._write_response to always compute a bytes body, set a correct Content-Length header, skip duplicate Content-Length from response headers, and write the encoded body. Add unit tests covering response framing (Content-Length and body bytes) and Unicode-safe JSON serialization/parse_response behavior.
Copy link
Contributor

@devloai devloai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Summary:

  • Adds _safe_json_dumps() fallback serializer to handle UnicodeDecodeError in IronPython 2.7 on French/accented Revit strings.
  • Updates HttpRequestHandler._write_response to always encode the body as bytes and set a correct Content-Length header, skipping any duplicate from response headers.
  • Adds two unit test files covering response framing and Unicode JSON serialization.

Review Summary:

The Content-Length framing fix is a solid, correct improvement and the overall approach (try json.dumps(ensure_ascii=True), fall back to _safe_json_dumps) is sound. However, there is a critical functional bug: the fallback function _safe_json_dumps checks isinstance(obj, str) which, in IronPython 2.7, will never match unicode objects — precisely the type that carries accented Revit strings. The docstring even incorrectly claims IronPython 2.7 unifies str and unicode (they are distinct; only IronPython 3 unifies them). This means the fallback is unreachable for the exact inputs it was designed to handle. Additionally, the new \n body written for all None-data responses (including 204 No Content) violates RFC 7230. The IPY2712 repo guideline was the key lens for catching the unicode type gap.

Follow-up suggestions:

  • @devloai fix the identified issues: add unicode to the isinstance check in _safe_json_dumps (using pyrevit.compat.PY2), guard the \n fallback against no-body status codes (204, 304), and handle inf/nan floats.

Handle float edge cases in _safe_json_dumps by detecting NaN and infinite values (using math.isnan/math.isinf) and returning "null" so the output remains valid JSON. Adds the math import and the corresponding check in pyrevitlib/pyrevit/routes/server/handler.py.
@vinnividivicci vinnividivicci marked this pull request as ready for review March 5, 2026 03:11
@vinnividivicci
Copy link
Author

@jmcouffin Bug fixes to the routes API to work properly with Revit, French, and other multilingual Revit installations with non English characters.

Apply consistent string quoting, spacing, and formatting across routes/server and tests. Changes include normalizing single to double quotes, consistent use of join and string concatenation, cleaning up pylint comment formatting, minor refactors (parentheses, trailing commas, line breaks), and small-safe-json-dumps tweaks. Tests updated to match the formatting changes. No functional behavior changes intended.
Make the _safe_json_dumps docstring a raw string literal to avoid accidental escape processing (e.g., \u sequences) on IronPython. Also adjust the unit test docstring capitalization for clarity in test_routes_server_unicode.py.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant