Skip to content

Commit

Permalink
Fix marshaler self suppression error (#5318)
Browse files Browse the repository at this point in the history
* Fix marshaler self suppression error

* spotless

* PR feedback
  • Loading branch information
jack-berg authored Mar 23, 2023
1 parent 29d9ebf commit c769d53
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,16 @@ public void writeSerializedMessage(byte[] protoSerialized, String jsonSerialized

@Override
public void close() throws IOException {
output.flush();
idCache.clear();
try {
output.flush();
idCache.clear();
} catch (IOException e) {
// If close is called automatically as part of try-with-resources, it's possible that
// output.flush() will throw the same exception. Re-throwing the same exception in a finally
// block triggers an IllegalArgumentException indicating illegal self suppression. To avoid
// this, we wrap the exception so a different instance is thrown.
throw new IOException(e);
}
}

private static Map<String, byte[]> getIdCache() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.exporter.internal.marshal;

import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;

import java.io.IOException;
import java.io.OutputStream;
import org.junit.jupiter.api.Test;

class MarshalerTest {

@Test
void writeTo_NoSelfSuppressionError() throws IOException {
Marshaler marshaler =
new Marshaler() {
@Override
public int getBinarySerializedSize() {
return 0;
}

@Override
protected void writeTo(Serializer output) throws IOException {
for (int i = 0; i < (50 * 1024 + 100) / 8; i++) {
output.writeFixed64Value(i);
}
}
};
OutputStream os = mock(OutputStream.class);

IOException error = new IOException("error!");
doThrow(error).when(os).write(any(), anyInt(), anyInt());
doThrow(error).when(os).write(any());
doThrow(error).when(os).write(anyInt());
doThrow(error).when(os).flush();

// If an exception is thrown writing bytes, and that same exception is thrown in the #close
// method cleaning up the AutoCloseable resource, an IllegalArgumentException will be thrown
// indicating illegal self suppression. Ensure an IOException is thrown instead.
assertThatThrownBy(() -> marshaler.writeBinaryTo(os)).isInstanceOf(IOException.class);
assertThatThrownBy(() -> marshaler.writeJsonTo(os)).isInstanceOf(IOException.class);
}
}

0 comments on commit c769d53

Please sign in to comment.