function varargout = pElementwiseUnaryOpWithCatch(fcn, data, varargin)
%pElementwiseUnaryOpWithCatch  Perform elementwise unary operations inside try-catch
%   D2 = codistributed.pElementwiseUnaryOpWithCatch(F, D1) performs the elementwise unary
%   operation F on all elements of D1 inside a try-catch block so as to achieve
%   collective error handling.  Any errors are thrown as the caller.

%   Copyright 2006-2020 The MathWorks, Inc.

narginchk(2, inf);
out = cell(1,nargout);

% Only first input should be distributed. Gather the rest and call on
% client if none still distributed.
distributedutil.CodistParser.verifyNonCodistributedInputs(varargin);
varargin = distributedutil.CodistParser.gatherElements(varargin);
if ~isa(data, 'codistributed')
    % Only the optional arguments were codistributed. Redirect to client
    % function.
    [out{:}] = fcn(data, varargin{:});
    varargout = out;
    return;
end

% Call the op on the local part. 
LP = getLocalPart(data);
codistr = getCodistributor(data);

try
    % Operate on the local part. All outputs will have same size as input.
    [out{:}] = distributedutil.syncOnError(fcn, LP, varargin{:});
catch E
    throwAsCaller(dispatchUndefinedFunctionException(E)); % Hide the implementation stack.
end

% Package all outputs back into codistributed
varargout = cellfun(@(lp) codistributed.pDoBuildFromLocalPart(lp, codistr), out, ...
    'UniformOutput', false);
end