Merge pull request #446 from dkorpel/error-dedup

com.d: deduplicate error handling of `Invoke`
This commit is contained in:
Adam D. Ruppe 2024-07-09 08:31:24 -04:00 committed by GitHub
commit 3e29c2d38d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 42 additions and 105 deletions

147
com.d
View File

@ -288,32 +288,8 @@ struct ComProperty {
&argError // arg error
);//, "Invoke");
import std.conv;
if(FAILED(hr)) {
if(hr == DISP_E_EXCEPTION) {
auto code = einfo.scode ? einfo.scode : einfo.wCode;
string source;
string description;
if(einfo.bstrSource) {
// this is really a wchar[] but it needs to be freed so....
source = einfo.bstrSource[0 .. SysStringLen(einfo.bstrSource)].to!string;
SysFreeString(einfo.bstrSource);
}
if(einfo.bstrDescription) {
description = einfo.bstrDescription[0 .. SysStringLen(einfo.bstrDescription)].to!string;
SysFreeString(einfo.bstrDescription);
}
if(einfo.bstrHelpFile) {
// FIXME: we could prolly use this too
SysFreeString(einfo.bstrHelpFile);
// and dwHelpContext
}
throw new ComException(code, description ~ " (from com source " ~ source ~ ")");
} else {
throw new ComException(hr, "Property get failed " ~ to!string(argError));
}
if (Exception e = exceptionFromComResult(hr, einfo, argError, "Property get")) {
throw e;
}
return ComResult(result);
@ -350,32 +326,8 @@ struct ComProperty {
VariantClear(&vargs[0]);
import std.conv;
if(FAILED(hr)) {
if(hr == DISP_E_EXCEPTION) {
auto code = einfo.scode ? einfo.scode : einfo.wCode;
string source;
string description;
if(einfo.bstrSource) {
// this is really a wchar[] but it needs to be freed so....
source = einfo.bstrSource[0 .. SysStringLen(einfo.bstrSource)].to!string;
SysFreeString(einfo.bstrSource);
}
if(einfo.bstrDescription) {
description = einfo.bstrDescription[0 .. SysStringLen(einfo.bstrDescription)].to!string;
SysFreeString(einfo.bstrDescription);
}
if(einfo.bstrHelpFile) {
// FIXME: we could prolly use this too
SysFreeString(einfo.bstrHelpFile);
// and dwHelpContext
}
throw new ComException(code, description ~ " (from com source " ~ source ~ ")");
} else {
throw new ComException(hr, "Property put failed " ~ to!string(argError));
}
if (Exception e = exceptionFromComResult(hr, einfo, argError, "Property put")) {
throw e;
}
return rhs;
@ -463,39 +415,48 @@ struct ComProperty {
}
}
import std.conv;
if(FAILED(hr)) {
if(hr == DISP_E_EXCEPTION) {
auto code = einfo.scode ? einfo.scode : einfo.wCode;
string source;
string description;
if(einfo.bstrSource) {
// this is really a wchar[] but it needs to be freed so....
source = einfo.bstrSource[0 .. SysStringLen(einfo.bstrSource)].to!string;
SysFreeString(einfo.bstrSource);
}
if(einfo.bstrDescription) {
description = einfo.bstrDescription[0 .. SysStringLen(einfo.bstrDescription)].to!string;
SysFreeString(einfo.bstrDescription);
}
if(einfo.bstrHelpFile) {
// FIXME: we could prolly use this too
SysFreeString(einfo.bstrHelpFile);
// and dwHelpContext
}
throw new ComException(code, description ~ " (from com source " ~ source ~ ")");
} else {
import std.conv;
throw new ComException(hr, "Call failed " ~ to!string(cast(void*) innerComObject_) ~ " " ~ to!string(dispid) ~ " " ~ to!string(argError));
}
if (Exception e = exceptionFromComResult(hr, einfo, argError, "Call")) {
throw e;
}
return ComResult(result);
}
}
/// Returns: `null` on success, a D Exception created from `einfo` and `argError`
/// in case the COM return `hr` signals failure
private Exception exceptionFromComResult(HRESULT hr, ref EXCEPINFO einfo, uint argError, string action)
{
import std.conv;
if(FAILED(hr)) {
if(hr == DISP_E_EXCEPTION) {
auto code = einfo.scode ? einfo.scode : einfo.wCode;
string source;
string description;
if(einfo.bstrSource) {
// this is really a wchar[] but it needs to be freed so....
source = einfo.bstrSource[0 .. SysStringLen(einfo.bstrSource)].to!string;
SysFreeString(einfo.bstrSource);
}
if(einfo.bstrDescription) {
description = einfo.bstrDescription[0 .. SysStringLen(einfo.bstrDescription)].to!string;
SysFreeString(einfo.bstrDescription);
}
if(einfo.bstrHelpFile) {
// FIXME: we could prolly use this too
SysFreeString(einfo.bstrHelpFile);
// and dwHelpContext
}
throw new ComException(code, description ~ " (from com source " ~ source ~ ")");
} else {
throw new ComException(hr, action ~ " failed " ~ to!string(argError));
}
}
return null;
}
///
struct ComClient(DVersion, ComVersion = IDispatch) {
ComVersion innerComObject_;
@ -584,32 +545,8 @@ struct ComClient(DVersion, ComVersion = IDispatch) {
}
}
import std.conv;
if(FAILED(hr)) {
if(hr == DISP_E_EXCEPTION) {
auto code = einfo.scode ? einfo.scode : einfo.wCode;
string source;
string description;
if(einfo.bstrSource) {
// this is really a wchar[] but it needs to be freed so....
source = einfo.bstrSource[0 .. SysStringLen(einfo.bstrSource)].to!string;
SysFreeString(einfo.bstrSource);
}
if(einfo.bstrDescription) {
description = einfo.bstrDescription[0 .. SysStringLen(einfo.bstrDescription)].to!string;
SysFreeString(einfo.bstrDescription);
}
if(einfo.bstrHelpFile) {
// FIXME: we could prolly use this too
SysFreeString(einfo.bstrHelpFile);
// and dwHelpContext
}
throw new ComException(code, description ~ " (from com source " ~ source ~ ")");
} else {
throw new ComException(hr, "Call failed " ~ memberName ~ " " ~ to!string(argError));
}
if (Exception e = exceptionFromComResult(hr, einfo, argError, "Call")) {
throw e;
}
return getFromVariant!(typeof(return))(result);