Skip to content

feat: Add support for proper exception handling#1694

Merged
kavirajk merged 6 commits intomainfrom
kavirajk/exception-tag-support
Dec 2, 2025
Merged

feat: Add support for proper exception handling#1694
kavirajk merged 6 commits intomainfrom
kavirajk/exception-tag-support

Conversation

@kavirajk
Copy link
Copy Markdown
Contributor

@kavirajk kavirajk commented Nov 2, 2025

Summary

Related: #1468

This PR adds support to extract the exception happens during mid-stream. Supports generic exception marker for both CH 24.11 and before.

Checklist

Delete items not relevant to your PR:

@kavirajk kavirajk force-pushed the kavirajk/exception-tag-support branch from 4e5ab72 to 6ae160a Compare December 1, 2025 09:48
@kavirajk kavirajk self-assigned this Dec 1, 2025
@kavirajk kavirajk marked this pull request as ready for review December 1, 2025 09:55
@kavirajk kavirajk requested a review from chernser December 1, 2025 09:56
conn_http.go Outdated
if n > 0 && captureBuffer != nil {
captureBuffer.Write(buf[:n])
}
if readErr != nil {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'd add some debug log here - when we failed, error

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done.

conn_http.go Outdated

// Try to read any remaining data
lr := &limitedReader{reader: reader, limit: 100 * 1024}
buf := make([]byte, 4096)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

it would require 25 times to call socket IO.
I think this can be increased to 10024 safely.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. Thanks.

I actually made a small change to it. Given the max exception block is 16KiB and when exception happens at the mid-stream, CH flushes the existing chunks (blocks) and start new one just for the exception.

So the exception would be the only thing present in this block. So just allocating 16KiB and reading it once should be good enough. Updated accordingly.

conn_http.go Outdated
// "__exception__" marker as binary data

// Try to read any remaining data
lr := &limitedReader{reader: reader, limit: 100 * 1024}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This relates to the block size. What if block size is 1Mb and exception is at the end?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

explained it in my last comment.

conn_http.go Outdated
dataStr := string(data)

// Verify exception marker exists
if !strings.Contains(dataStr, "__exception__") {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

this is redundant because next if checks it again using proper way.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

good catch. Removed it.

conn_http.go Outdated
}

// Skip the exception tag (16 bytes) + \r\n
if pos+16+2 < len(dataStr) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

16 looks very megical - lets create a constant what ideally should be calculated from marker string (what we actually do a few lines above.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Make sense. Moved it to local constants :)

conn_http.go Outdated
}

// Skip past first __exception__\r\n
pos := firstMarker + len("__exception__")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

we can save len("__exception__") for further use.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Make sense. Moved it to local constants as well :)

1. Move magic numbers to well defined constants
2. Fix the block size when decoding

Signed-off-by: Kaviraj <[email protected]>
@kavirajk kavirajk merged commit b4fd33b into main Dec 2, 2025
20 of 21 checks passed
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.

2 participants